Pull in private copy of libarchive to add pcmpress-specific functionality.

First step to add packPNM support.
This commit is contained in:
Moinak Ghosh 2014-09-11 18:34:43 +05:30
parent 9feee0a36d
commit 9ecbbbafd0
193 changed files with 189686 additions and 67 deletions

View file

@ -146,6 +146,11 @@ PJPGHDRS = filters/packjpg/aricoder.h filters/packjpg/bitops.h filters/packjpg/d
filters/packjpg/packjpglib.h filters/packjpg/pjpgtbl.h
PJPGOBJS = $(PJPGSRCS:.cpp=.o)
PPNMSRCS = filters/packpnm/packpnm.cpp archive/ppnm_helper.cpp
PPNMHDRS = filters/packjpg/aricoder.h filters/packjpg/bitops.h filters/packpnm/ppnmbitlen.h \
filters/packpnm/packpnmlib.h filters/packpnm/ppnmtbl.h
PPNMOBJS = $(PPNMSRCS:.cpp=.o)
DISPACKSRCS = filters/dispack/dis.cpp
DISPACKHDRS = filters/dispack/dis.hpp filters/dispack/types.hpp
DISPACKOBJS = $(DISPACKSRCS:.cpp=.o)
@ -222,21 +227,22 @@ BASE_CPPFLAGS = -I. -I./lzma -I./lzfx -I./lz4 -I./rabin -I./bsdiff -DNODEFAULT_P
-I./crypto/keccak -I./filters/transpose -I./crypto/blake2 $(EXTRA_CPPFLAGS) \
-I./crypto/xsalsa20 -I./archive -pedantic -Wall -I./filters -fno-strict-aliasing \
-Wno-unused-but-set-variable -Wno-enum-compare \
@COMPAT_CPPFLAGS@ @XSALSA20_DEBUG@ @LIBARCHIVE_INC@ -I./filters/packjpg
@COMPAT_CPPFLAGS@ @XSALSA20_DEBUG@ -I@LIBARCHIVE_DIR@/libarchive -I./filters/packjpg \
-I./filters/packpnm
COMMON_CPPFLAGS = $(BASE_CPPFLAGS) -std=gnu99
COMMON_CPPFLAGS_cpp = $(BASE_CPPFLAGS)
COMMON_VEC_FLAGS = -ftree-vectorize
COMMON_LOOP_OPTFLAGS = $(VEC_FLAGS) -floop-interchange -floop-block
RPATH=@RPATH@
DTAGS=@DTAGS@
LDLIBS = -ldl -L./buildtmp -Wl,$(RPATH)@LIBBZ2_DIR@ -lbz2 -L./buildtmp -Wl,$(RPATH)@LIBZ_DIR@ -lz -lm @LIBBSCLFLAGS@ \
-L./buildtmp -Wl,$(RPATH)@OPENSSL_LIBDIR@ -lcrypto @LRT@ -Wl,$(RPATH)@LIBARCHIVE_DIR@ -larchive $(EXTRA_LDFLAGS) \
LDLIBS = -ldl -liconv -L./buildtmp -Wl,$(RPATH)@LIBBZ2_DIR@ -lbz2 -L./buildtmp -Wl,$(RPATH)@LIBZ_DIR@ -lz -lm @LIBBSCLFLAGS@ \
-L./buildtmp -Wl,$(RPATH)@OPENSSL_LIBDIR@ -lcrypto @LRT@ -L@LIBARCHIVE_DIR@/.libs -larchive $(EXTRA_LDFLAGS) \
-Wl,$(RPATH)/usr/lib$(DTAGS) -Wl,$(RPATH)/usr/lib64$(DTAGS)
OBJS = $(MAINOBJS) $(LZMAOBJS) $(PPMDOBJS) $(LZFXOBJS) $(LZ4OBJS) $(CRCOBJS) \
$(RABINOBJS) $(BSDIFFOBJS) $(LZPOBJS) $(DELTA2OBJS) @LIBBSCWRAPOBJ@ $(SKEINOBJS) \
$(SKEIN_BLOCK_OBJ) @SHA2ASM_OBJS@ @SHA2_OBJS@ $(KECCAK_OBJS) $(KECCAK_OBJS_ASM) \
$(TRANSP_OBJS) $(CRYPTO_OBJS) $(ZLIB_OBJS) $(BZLIB_OBJS) $(XXHASH_OBJS) $(BLAKE2_OBJS) \
@CRYPTO_COMPAT_OBJS@ $(CRYPTO_ASM_OBJS) $(ARCHIVEOBJS) $(PJPGOBJS) $(DISPACKOBJS)
@CRYPTO_COMPAT_OBJS@ $(CRYPTO_ASM_OBJS) $(ARCHIVEOBJS) $(PJPGOBJS) $(DISPACKOBJS) $(PPNMOBJS)
DEBUG_LINK = $(GPP) -pthread @LIBBSCGEN_OPT@ @EXTRA_OPT_FLAGS@ -fopenmp -fPIC
DEBUG_COMPILE = $(GCC) -g -c @EXTRA_OPT_FLAGS@ -fPIC @USE_CLANG_AS@
@ -314,6 +320,10 @@ $(PJPGOBJS): $(PJPGSRCS) $(PJPGHDRS)
$(COMPILE_cpp) $(COMMON_VEC_FLAGS) @SSE_OPT_FLAGS@ @USE_CLANG_AS@ -O2 -fsched-spec-load \
$(VEC_FLAGS) -DBUILD_LIB $(COMMON_CPPFLAGS_cpp) $(@:.o=.cpp) -o $@
$(PPNMOBJS): $(PPNMSRCS) $(PPNMHDRS)
$(COMPILE_cpp) $(COMMON_VEC_FLAGS) @SSE_OPT_FLAGS@ @USE_CLANG_AS@ -O2 -fsched-spec-load \
$(VEC_FLAGS) -DBUILD_LIB $(COMMON_CPPFLAGS_cpp) $(@:.o=.cpp) -o $@
$(DISPACKOBJS): $(DISPACKSRCS) $(DISPACKHDRS)
$(COMPILE_cpp) $(COMMON_VEC_FLAGS) @DEBUG_STATS_CPPFLAGS@ @SSE_OPT_FLAGS@ @USE_CLANG_AS@ -O2 -fsched-spec-load \
-Wno-variadic-macros $(VEC_FLAGS) $(COMMON_CPPFLAGS_cpp) $(@:.o=.cpp) -o $@
@ -382,10 +392,13 @@ $(MAINOBJS): $(MAINSRCS) $(MAINHDRS)
$(PROGOBJS): $(PROGSRCS) $(PROGHDRS)
$(COMPILE) $(GEN_OPT) $(LOOP_OPTFLAGS) $(CPPFLAGS) $(@:.o=.c) -o $@
Libarchive:
(cd @LIBARCHIVE_DIR@; make)
$(LIBBSCLIB):
(cd $(LIBBSCDIR); make CC=$(GPP) OPTFLAGS="-O3 @SSE_OPT_FLAGS@ @USE_CLANG_AS@")
$(LIB): $(OBJS) $(LIBBSCLIB)
$(LIB): Libarchive $(OBJS) $(LIBBSCLIB)
$(LINK.LIB) -Wl,-soname$(LIB).$(LIBVER) -o $(LIB).$(LIBVER) $(OBJS) $(LDLIBS)
ln -sf $(LIB).$(LIBVER) $(LIB)
@ -393,7 +406,7 @@ $(LIB): $(OBJS) $(LIBBSCLIB)
mkdir -p buildtmp
$(LINK.PROG) -o $@ $(PROGOBJS) $(LDLIBS) -L. -l$(LINKLIB)
$(PROG): $(LIB) $(PROGOBJS) ./buildtmp/$(PROG)
$(PROG): $(LIB) $(PROGOBJS) ./buildtmp/$(PROG)
cat utils/pcompress.sh | sed "s#<PC_PATH>#`pwd`#" > pcompress
chmod +x pcompress
@ -404,11 +417,13 @@ clean:
$(RM) buildtmp/$(PROG) $(OBJS) $(PROGOBJS) $(BAKFILES) $(LIB) $(LIB).$(LIBVER)
$(RM) test.log
$(RM_RF) test/datafiles
(cd @LIBARCHIVE_DIR@; make clean)
distclean: clean
$(RM) Makefile
(cd $(LIBBSCDIR); make clean)
$(RM_RF) buildtmp
(cd @LIBARCHIVE_DIR@; make distclean; rm -rf Makefile.orig tar test test_utils cpio libarchive/test)
install: $(PROG)
@mkdir -p $(DESTDIR)$(PREFIX)/bin

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,60 @@
The libarchive distribution as a whole is Copyright by Tim Kientzle
and is subject to the copyright notice reproduced at the bottom of
this file.
Each individual file in this distribution should have a clear
copyright/licensing statement at the beginning of the file. If any do
not, please let me know and I will rectify it. The following is
intended to summarize the copyright status of the individual files;
the actual statements in the files are controlling.
* Except as listed below, all C sources (including .c and .h files)
and documentation files are subject to the copyright notice reproduced
at the bottom of this file.
* The following source files are also subject in whole or in part to
a 3-clause UC Regents copyright; please read the individual source
files for details:
libarchive/archive_entry.c
libarchive/archive_read_support_filter_compress.c
libarchive/archive_write_set_filter_compress.c
libarchive/mtree.5
tar/matching.c
* The following source files are in the public domain:
tar/getdate.c
* The build files---including Makefiles, configure scripts,
and auxiliary scripts used as part of the compile process---have
widely varying licensing terms. Please check individual files before
distributing them to see if those restrictions apply to you.
I intend for all new source code to use the license below and hope over
time to replace code with other licenses with new implementations that
do use the license below. The varying licensing of the build scripts
seems to be an unavoidable mess.
Copyright (c) 2003-2009 <author(s)>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer
in this position and unchanged.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,35 @@
More complete build documentation is available on the libarchive
Wiki: http://libarchive.googlecode.com/
On most Unix-like systems, you should be able to install libarchive,
bsdtar, and bsdcpio using the following common steps:
./configure
make
make install
If you need to customize the target directories or otherwise adjust
the build setting, use
./configure --help
to list the configure options.
If you are developing libarchive and need to update the
configure script and other build files:
/bin/sh build/autogen.sh
To create a distribution, please use the 'distcheck' target:
/bin/sh build/autogen.sh && ./configure && make distcheck
On Unix-like and non-Unix-like systems, use the "cmake" utility (available from
http://cmake.org/) to generate suitable build files for your platform.
Cmake requires the name of the directory containing CmakeLists.txt and
the "generator" to use for your build environment. For example, to
build with Xcode on Mac OS, you can use the following command:
cmake -G "Xcode" ~/libarchive-download-dir/
The result will be appropriate makefiles, solution files, or project
files that can be used with the corresponding development tool.
The default on Unix-like systems is to generate Makefiles, so you
can also use cmake instead of the configure script:
cmake ~/libarchive-download-dir/
make
make install
See the libarchive Wiki or the cmake site for further documentation.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,626 @@
Feb 09, 2013: libarchive 3.1.2 released
Jan 28, 2013: libarchive's new website moved to http://www.libarchive.org.
Jan 13, 2013: libarchive 3.1.1 released
Jan 13, 2013: libarchive 3.1.0 released
Dec 07, 2012: Implement functions to manually set the format and filters used.
Nov 11, 2012: Add support for __MACOSX directory in Zip archives, which resource
forks are stored in.
Oct 20, 2012: Add support for writing v7 tar format.
Oct 09, 2012: Add support for grzip compression.
Oct 07, 2012: Introduce b64encode filter.
Oct 07, 2012: Introduce uuencode filter.
Oct 06, 2012: Add support for lzop.
Sep 27, 2012: Implement function used to seek within data blocks.
(Currently only supported for uncompressed RAR archives).
Apr 22, 2012: Add basic archive read and write filter support for lrzip.
Mar 27, 2012: libarchive 3.0.4 released
Feb 05, 2012: libarchive development now hosted at GitHub.
http://libarchive.github.com/
Feb 05, 2012: libarchive's issue tracker remains at Google Code.
http://code.google.com/p/libarchive/issues/list
Feb 05, 2012: libarchive's mailing lists remain at Google Groups.
Dec 24, 2011: libarchive 3.0.2 released
Dec 23, 2011: Various fixes merged from FreeBSD
Dec 23, 2011: Symlink support in Zip reader and writer
Dec 23, 2011: Robustness fixes to 7Zip reader
Nov 27, 2011: libarchive 3.0.1b released
Nov 26, 2011: 7Zip reader
Nov 26, 2011: Small fixes to ISO and Zip to improve robustness with corrupted input
Nov 24, 2011: Improve streaming Zip reader's support for uncompressed entries
Nov 20, 2011: New seeking Zip reader supports SFX Zip archives
Nov 20, 2011: Build fixes on Windows
Nov 13, 2011: libarchive 3.0.0a released
Nov 06, 2011: Update shared-library version calculations for libarchive 3.x
Sep 04, 2011: Fix tar -s; follow GNU tar for controlling hardlink/symlink substitutions
Aug 18, 2011: Fix reading ISO images built by NetBSD's mkisofs
Aug 15, 2011: Old archive_read_support_compression_XXX functions are deprecated and
will disappear in libarchive 4.0.
Jun 26, 2011: RAR reader
Jun 16, 2011: Add tar:compat-2x option to emulate broken libarchive 2.x
handling of pax UTF-8 headers
Apr 25, 2011: Refactor read_open() into a collection of single-item setters;
support the old interfaces as wrappers
Apr 12, 2011: Split disk writer into separate POSIX and Windows implementations
Apr 10, 2011: Improvements to character translations on Windows.
Mar 30, 2011: More work to return errors instead of calling abort()
Mar 23, 2011: Add charset option to many writers to control MBCS filenames
Mar 17, 2011: Overhauled support for per-format extension options
Mar 17, 2011: Track character set used for mbcs strings, support
translating to/from user-specified locale
Mar 09, 2011: Recognize mtree files without requiring a signature
Mar 06, 2011: Use iconv to convert to/from Unicode instead of making bad
assumptions about the C90 character set translation functions
Feb 17, 2011: Fixes for AIX, TRU64, and other platforms
Dec 22, 2010: CAB reader
Dec 20, 2010: LHA/LZH reader
Jul 03, 2010: minitar example demonstrates archive_read_disk directory traversal
Jun 29, 2010: Many improvements to ISO reader compatibility
Jun 26, 2010: Use larger buffers when copy files into an archive
Jun 18, 2010: Reimplement Mac OS extensions in libarchive
Jun 09, 2010: archive_read_disk now supports traversals
May 28, 2010: XAR writer
May 16, 2010: Fix ^T handling; don't exit on interrupted reads and writes
May 09, 2010: Improved detection of platform-specific crypto support
May 04, 2010: lzip read and write filters
May 01, 2010: New options: tar --gid --gname --uid --uname
Apr 28, 2010: Use Red-black tree for ISO reader/writer to improve performance
Apr 17, 2010: Minimal writer for legacy GNU tar format
Mar 12, 2010: Don't dereference symlinks on Linux when reading ACLs.
Mar 06, 2010: Fix build when an older libarchive is already installed
Feb 28, 2010: Relax handling of state failures; misuse by clients now generally
results in a sticky ARCHIVE_FATAL rather than a visit to abort()
Feb 25, 2010: ISO writer
Feb 21, 2010: Split many man pages into smaller chunks.
Feb 21, 2010: Performance: Cheat on block sizes when reading archives from disk.
Feb 21, 2010: Use int64_t instead of off_t, dev_t, ino_t, uid_t, and gid_t
Feb 20, 2010: Document new ACL functions.
Feb 19, 2010: Support multiple write filters
Feb 07, 2010: Remove some legacy libarchive 1.x APIs
Feb 04, 2010: Read afio headers
Feb 02, 2010: Archive sparse files compatibly with GNU tar
Feb 01, 2010: Integrate Apple extensions for Mac OS extended attributes into bsdtar
Jan 31, 2010: Support cpio -V
Feb 04, 2010: libarchive 2.8.0 released
Jan 17, 2010: Fix error handling for 'echo nonexistent | cpio -o'
Jan 17, 2010: Don't use futimes() on Cygwin
Jan 02, 2010: libarchive 2.7.902a released (test release for 2.8)
Jan 02, 2010: Fix tar/test/test_windows on MinGW
Jan 02, 2010: Fix memory leaks in libarchive tests
Jan 01, 2010: Fix memory leak when filter startup fails
Dec 27, 2009: libarchive 2.7.901a released (test release for 2.8)
Aug 04, 2009: libarchive 2.7.1 released
Jul 20, 2009: Suppress bogus warning about unxz
Jul 19, 2009: Support Cygwin 1.7
Jun 11, 2009: Support lzma/xz files compressed with larger buffer sizes.
May 24, 2009: Handle gzip files signed with OpenBSD "gzsig" program.
May 07, 2009: Avoid false failures when reading from pipe.
Apr 16, 2009: libarchive 2.7.0 released
Apr 10, 2009: libarchive 2.6.992a released
Apr 09, 2009: Fix SIGPIPE issue building with MSVC.
Apr 09, 2009: Fix several minor memory leaks in libarchive and libarchive_test
Apr 08, 2009: libarchive 2.6.991a released
Apr 07, 2009: Additional tests added to bsdcpio_test
Apr 01, 2009: libarchive 2.6.990a released
Apr 01, 2009: Use command-line gunzip, bunzip2, unxz, unlzma for
decompression if the library is built without suitable
libraries. The setup functions return ARCHIVE_WARN
in this case so clients can adapt if necessary.
Apr 01, 2009: Use getpw*_r and getgr*_r functions for thread-safety.
Mar 24, 2009: Add archive_read_next_header2(), which is up to 25%
more efficient for some clients; from Brian Harring.
Mar 22, 2009: PDF versions of manpages are now included in the distribution.
Mar, 2009: Major work to improve Cygwin build by Charles Wilson.
Feb/Mar, 2009: Major work on cmake build support, mostly by Michihiro NAKAJIMA.
Feb/Mar, 2009: Major work on Visual Studio support by Michihiro NAKAJIMA.
All tests now pass.
Feb 25, 2009: Fix Debian Bug #516577
Feb 21, 2009: Yacc is no longer needed to build; date parser rewritten in C.
Jan/Feb, 2009: Mtree work by Michihiro.
Feb, 2009: Joliet support by Andreas Henriksson.
Jan/Feb, 2009: New options framework by Michihiro.
Feb, 2009: High-res timestamps on Tru64, AIX, and GNU Hurd, by Björn Jacke.
Jan 18, 2009: Extended attributes work on FreeBSD and Linux now with pax format.
Jan 07, 2009: New archive_read_disk_entry_from_file() knows about ACLs,
extended attributes, etc so that bsdtar and bsdcpio don't require
such system-specific knowledge.
Jan 03, 2009: Read filter system extensively refactored. In particular,
read filter pipelines are now built out automatically and individual
filters should be much easier to implement. Documentation on the
Googlecode Wiki explains how to implement new filters.
Dec 28, 2008: Many Windows/Visual Studio fixes from Michihiro NAKAJIMA.
Dec 28, 2008: Main libarchive development moved from FreeBSD Perforce
server to Google Code. This should make it easier for more
people to participate in libarchive development.
Dec 28, 2008: libarchive 2.6.0 released
Dec 25, 2008: libarchive 2.5.905a released
Dec 10, 2008: libarchive 2.5.904a released
Dec 04, 2008: libarchive 2.5.903a released
Nov 09, 2008: libarchive 2.5.902a released
Nov 08, 2008: libarchive 2.5.901a released
Nov 08, 2008: Start of pre-release testing for libarchive 2.6
Nov 07, 2008: Read filter refactor: The decompression routines just
consume and produce arbitrarily-sized blocks. The reblocking
from read_support_compression_none() has been pulled into the
read core. Also, the decompression bid now makes multiple
passes and stacks read filters.
Oct 21, 2008: bsdcpio: New command-line parser.
Oct 19, 2008: Internal read_ahead change: short reads are now an error
Oct 06, 2008: bsdtar: option parser no longer uses getopt_long(),
gives consistent option parsing on all platforms.
Sep 19, 2008: Jaakko Heinonen: shar utility built on libarchive
Sep 17, 2008: Pedro Giffuni: birthtime support
Sep 17, 2008: Miklos Vajna: lzma reader and test. Note: I still have
some concerns about the auto-detection (LZMA file format
doesn't support auto-detection well), so this is not yet
enabled under archive_read_support_compression_all(). For
now, you must call archive_read_support_compression_lzma() if
you want LZMA read support.
Sep 11, 2008: Ivailo Petrov: Many fixes to Windows build, new solution files
Jul 26, 2008: archive_entry now tracks which values have not been set.
This helps zip extraction (file size is often "unknown") and
time restores (tar usually doesn't know atime).
Jul 26, 2008: Joerg Sonnenberger: Performance improvements to shar writer
Jul 25, 2008: Joerg Sonnenberger: mtree write support
Jul 02, 2008: libarchive 2.5.5 released
Jul 02, 2008: libarchive 2.5.5b released
Jul 01, 2008: bsdcpio is being used by enough people, we can call it 1.0.0 now
Jun 20, 2008: bsdcpio: If a -l link fails with EXDEV, copy the file instead
Jun 19, 2008: bsdcpio: additional long options for better GNU cpio compat
Jun 15, 2008: Many small portability and bugfixes since 2.5.4b.
May 25, 2008: libarchive 2.5.4b released
May 21, 2008: Joerg Sonnenberger: fix bsdtar hardlink handling for newc format
May 21, 2008: More progress on Windows building. Thanks to "Scott"
for the Windows makefiles, thanks to Kees Zeelenberg for
code contributions.
May 21, 2008: Fix a number of non-exploitable integer and buffer overflows,
thanks to David Remahl at Apple for pointing these out.
May 21, 2008: Colin Percival: SIGINFO or SIGUSR1 to bsdtar prints progress info
May 16, 2008: bsdtar's test harness no longer depends on file ordering.
This was causing spurious test failures on a lot of systems.
Thanks to Bernhard R. Link for the diagnosis.
May 14, 2008: Joerg Sonnenberger: -s substitution support for bsdtar
May 13, 2008: Joerg Sonnenberger: Many mtree improvements
May 11, 2008: Joerg Sonnenberger: fix hardlink extraction when
hardlinks have different permissions from original file
April 30, 2008: Primary libarchive work has been moved into the FreeBSD
project's Perforce repository: http://perforce.freebsd.org/
The libarchive project can be browsed at
//depot/user/kientzle/libarchive-portable
Direct link: http://preview.tinyurl.com/46mdgr
May 04, 2008: libarchive 2.5.3b released
* libarchive: Several fixes to link resolver to address bsdcpio crashes
* bsdcpio: -p hardlink handling fixes
* tar/pax: Ensure ustar dirnames end in '/'; be more careful about
measuring filenames when deciding what pathname fields to use
* libarchive: Mark which entry strings are set; be accurate about
distinguishing empty strings ("") from unset ones (NULL)
* tar: Don't crash reading entries with empty filenames
* libarchive_test, bsdtar_test, bsdcpio_test: Better detaults:
run all tests, delete temp dirs, summarize repeated failures
* -no-undefined to libtool for Cygwin
* libarchive_test: Skip large file tests on systems with 32-bit off_t
* iso9660: Don't bother trying to find the body of an empty file;
this works around strange behavior from some ISO9660 writers
* tar: allow -r -T to be used together
* tar: allow --format with -r or -u
* libarchive: Don't build archive.h
May 04, 2008: Simplified building: archive.h is no longer constructed
This may require additional #if conditionals on some platforms.
Mar 30, 2008: libarchive 2.5.1b released
Mar 15, 2008: libarchive 2.5.0b released
Mar 15, 2008: bsdcpio now seems to correctly write hardlinks into newc,
ustar, and old cpio archives. Just a little more testing before
bsdcpio 1.0 becomes a reality.
Mar 15, 2008: I think the new linkify() interface is finally handling
all known hardlink strategies.
Mar 15, 2008: Mtree read fixes from Joerg Sonnenberger.
Mar 15, 2008: Many new bsdtar and bsdcpio options from Joerg Sonnenberger.
Mar 15, 2008: test harnesses no longer require uudecode; they
now have built-in decoding logic that decodes the reference
files as they are needed.
Mar 14, 2008: libarchive 2.4.14 released; identical to 2.4.13 except for
a point fix for gname/uname mixup in pax format that was introduced
with the UTF-8 fixes.
Feb 26, 2008: libarchive 2.4.13 released
Feb 25, 2008: Handle path, linkname, gname, or uname that can't be converted
to/from UTF-8. Implement "hdrcharset" attribute from SUS-2008.
Feb 25, 2008: Fix name clash on NetBSD.
Feb 18, 2008: Fix writing empty 'ar' archives, per Kai Wang
Feb 18, 2008: [bsdtar] Permit appending on block devices.
Feb 09, 2008: New "linkify" resolver to help with newc hardlink writing;
bsdcpio still needs to be converted to use this.
Feb 02, 2008: Windows compatibility fixes from Ivailo Petrov, Kees Zeelenberg
Jan 30, 2008: Ignore hardlink size for non-POSIX tar archives.
Jan 22, 2008: libarchive 2.4.12 released
Jan 22, 2008: Fix bad padding when writing symlinks to newc cpio archives.
Jan 22, 2008: Verify bsdcpio_test by getting it to work against GNU cpio 2.9.
bsdcpio_test complains about missing options (-y and -z), format
of informational messages (--version, --help), and a minor formatting
issue in odc format output. After this update, bsdcpio_test uncovered
several more cosmetic issues in bsdcpio, all now fixed.
Jan 22, 2008: Experimental support for self-extracting Zip archives.
Jan 22, 2008: Extend hardlink restore strategy to work correctly with
hardlinks extracted from newc cpio files. (Which store the body
only with the last occurrence of a link.)
Dec 30, 2007: libarchive 2.4.11 released
Dec 30, 2007: Fixed a compile error in bsdcpio on some systems.
Dec 29, 2007: libarchive 2.4.10 released
Dec 29, 2007: bsdcpio 0.9.0 is ready for wider use.
Dec 29, 2007: Completed initial test harness for bsdcpio.
Dec 22, 2007: libarchive 2.4.9 released
Dec 22, 2007: Implement the remaining options for bsdcpio: -a, -q, -L, -f,
pattern selection for -i and -it.
Dec 13, 2007: libarchive 2.4.8 released
Dec 13, 2007: gzip and bzip2 compression now handle zero-byte writes correctly,
Thanks to Damien Golding for bringing this to my attention.
Dec 12, 2007: libarchive 2.4.7 released
Dec 10, 2007: libarchive 2.4.6 released
Dec 09, 2007: tar/test/test_copy.c verifies "tar -c | tar -x" copy pipeline
Dec 07, 2007: Fix a couple of minor memory leaks.
Dec 04, 2007: libarchive 2.4.5 released
Dec 04, 2007: Fix cpio/test/test_write_odc by setting the umask first.
Dec 03, 2007: libarchive 2.4.4 released
Dec 03, 2007: New configure options --disable-xattr and --disable-acl,
thanks to Samuli Suominen.
Dec 03, 2007: libarchive 2.4.3 released
Dec 03, 2007: Thanks to Lapo Luchini for sending me a ZIP file that
libarchive couldn't handle. Fixed a bug in handling of
"length at end" flags in ZIP files.
Dec 03, 2007: Fixed bsdcpio -help, bsdtar -help tests.
Dec 02, 2007: First cut at real bsdtar test harness.
Dec 02, 2007: libarchive 2.4.2 released
Dec 02, 2007: libarchive 2.4.1 released
Dec 02, 2007: Minor fixes, rough cut of mdoc-to-man conversion for
man pages.
Oct 30, 2007: libarchive 2.4.0 released
Oct 30, 2007: Minor compile fix thanks to Joerg Schilling.
Oct 30, 2007: Only run the format auction once at the beginning of the
archive. This is simpler and supports better error recovery.
Oct 29, 2007: Test support for very large entries in tar archives:
libarchive_test now exercises entries from 2GB up to 1TB.
Oct 27, 2007: libarchive 2.3.5 released
Oct 27, 2007: Correct some unnecessary internal data copying in the
"compression none" reader and writer; this reduces user time
by up to 2/3 in some tests. (Thanks to Jan Psota for
publishing his performance test results to GNU tar's bug-tar
mailing list; those results pointed me towards this problem.)
Oct 27, 2007: Fix for skipping archive entries that are exactly
a multiple of 4G on 32-bit platforms.
Oct 25, 2007: Fix for reading very large (>8G) tar archives; this was
broken when I put in support for new GNU tar sparse formats.
Oct 20, 2007: Initial work on new pattern-matching code for cpio; I
hope this eventually replaces the code currently in bsdtar.
Oct 08, 2007: libarchive 2.3.4 released
Oct 05, 2007: Continuing work on bsdcpio test suite.
Oct 05, 2007: New cpio.5 manpage, updates to "History" of bsdcpio.1 and
bsdtar.1 manpages.
Oct 05, 2007: Fix zip reader to immediately return EOF if you try
to read body of non-regular file. In particular, this fixes
bsdtar extraction of zip archives.
Sep 30, 2007: libarchive 2.3.3 released
Sep 26, 2007: Rework Makefile.am so that the enable/disable options
actually do the right things.
Sep 26, 2007: cpio-odc and cpio-newc archives no longer write bodies
for non-regular files.
Sep 26, 2007: Test harness for bsdcpio is in place, needs more tests written.
This is much nicer than the ragtag collection of test scripts
that bsdtar has.
Sep 20, 2007: libarchive 2.3.2 released
Sep 20, 2007: libarchive 2.3.1 broke bsdtar because the archive_write_data()
fix was implemented incorrectly.
Sep 16, 2007: libarchive 2.3.1 released
Sep 16, 2007: Many fixes to bsdcpio 0.3: handle hardlinks with -p, recognize
block size on writing, fix a couple of segfaults.
Sep 16, 2007: Fixed return value from archive_write_data() when used
with archive_write_disk() to match the documentation and other
instances of this same function.
Sep 15, 2007: Add archive_entry_link_resolver, archive_entry_strmode
Sep 11, 2007: libarchive 2.2.8 released
Sep 09, 2007: bsdcpio 0.2 supports most (not yet all) of the old POSIX spec.
Sep 01, 2007: libarchive 2.2.7 released
Aug 31, 2007: Support for reading mtree files, including an mtree.5 manpage
(A little experimental still.)
Aug 18, 2007: Read gtar 1.17 --posix --sparse entries.
Aug 13, 2007: Refined suid/sgid restore handling; it is no longer
an error if suid/sgid bits are dropped when you request
perm restore but don't request owner restore.
Aug 06, 2007: Use --enable-bsdcpio if you want to try bsdcpio
Aug 05, 2007: libarchive 2.2.6 released
Aug 05, 2007: New configure option --disable-bsdtar, thanks to Joerg
Sonnenberger.
Aug 05, 2007: Several bug fixes from FreeBSD CVS repo.
Jul 13, 2007: libarchive 2.2.5 released
Jul 12, 2007: libarchive 2.2.4 released
Jul 12, 2007: Thanks to Colin Percival's help in diagnosing and
fixing several critical security bugs. Details available at
http://security.freebsd.org/advisories/FreeBSD-SA-07:05.libarchive.asc
May 26, 2007: libarchive 2.2.3 released
May 26, 2007: Fix memory leaks in ZIP reader and shar writer, add some
missing system headers to archive_entry.h, dead code cleanup
from Colin Percival, more tests for gzip/bzip2, fix an
EOF anomaly in bzip2 decompression.
May 12, 2007: libarchive 2.2.2 released
May 12, 2007: Fix archive_write_disk permission restore by cloning
entry passed into write_header so that permission info is
still available at finish_entry time. (archive_read_extract()
worked okay because it held onto the passed-in entry, but
direct consumers of archive_write_disk would break). This
required fixing archive_entry_clone(), which now works and has
a reasonably complete test case.
May 10, 2007: Skeletal cpio implementation.
May 06, 2007: libarchive 2.2.1 released
May 06, 2007: Flesh out a lot more of test_entry.c so as to catch
problems such as the device node breakage before releasing <sigh>.
May 05, 2007: Fix a bad bug introduced in 2.1.9 that broke device
node entries in tar archives.
May 03, 2007: Move 'struct stat' out of archive_entry core as well.
This removes some portability headaches and fixes a bunch
of corner cases that arise when manipulating archives on
dissimilar systems.
Apr 30, 2007: libarchive 2.1.10 released
Apr 31, 2007: Minor code cleanup.
Apr 24, 2007: libarchive 2.1.9 released
Apr 24, 2007: Fix some recently-introduced problems with libraries
(Just let automake handle it and it all works much better.)
Finish isolating major()/minor()/makedev() in archive_entry.c.
Apr 23, 2007: libarchive 2.1.8 released
Apr 23, 2007: Minor fixes found from building on MacOS X
Apr 22, 2007: libarchive 2.1.7 released
Apr 22, 2007: Eliminated all uses of 'struct stat' from the
format readers/writers. This should improve portability;
'struct stat' is now only used in archive_entry and in
code that actually touches the disk.
Apr 17, 2007: libarchive 2.1.6 released
Libarchive now compiles and passes all tests on Interix.
Apr 16, 2007: libarchive 2.1.5 released
Apr 15, 2007: libarchive 2.1b2 released
Apr 15, 2007: New libarchive_internals.3 documentation of internal APIs.
Not complete, but should prove helpful.
Apr 15, 2007: Experimental "read_compress_program" and "write_compress_program"
for using libarchive with external compression. Not yet
well tested, and likely has portability issues. Feedback
appreciated.
Apr 14, 2007: libarchive 2.0.31 released
Apr 14, 2007: More fixes for Interix, more 'ar' work
Apr 14, 2007: libarchive 2.0.30 released
Apr 13, 2007: libarchive now enforces trailing '/' on dirs
written to tar archives
Apr 11, 2007: libarchive 2.0.29 released
Apr 11, 2007: Make it easier to statically configure for different platforms.
Apr 11, 2007: Updated config.guess, config.sub, libtool
Apr 06, 2007: libarchive 2.0.28 released
Apr 06, 2007: 'ar' format read/write support thanks to Kai Wang.
Apr 01, 2007: libarchive 2.0.27 released
Mar 31, 2007: Several minor fixes from Colin Percival and Joerg Sonnenberger.
Mar 12, 2007: libarchive 2.0.25 released
Mar 12, 2007: Fix broken --unlink flag.
Mar 11, 2007: libarchive 2.0.24 released
Mar 10, 2007: Correct an ACL blunder that causes any ACL with an entry
that refers to a non-existent user or group to not be restored correctly.
The fix both makes the parser more tolerant (so that archives created
with the buggy ACLs can be read now) and corrects the ACL formatter.
Mar 10, 2007: More work on test portability to Linux.
Mar 10, 2007: libarchive 2.0.22 released
Mar 10, 2007: Header cleanups; added linux/fs.h, removed
some unnecessary headers, added #include guards in bsdtar.
If you see any obvious compile failures from this, let me know.
Mar 10, 2007: Work on bsdtar test scripts: not yet robust enough
to enable as part of "make check", but getting better.
Mar 10, 2007: libarchive now returns ARCHIVE_FAILED when
a header write fails in a way that only affects this item.
Less bad than ARCHIVE_FATAL, but worse than ARCHIVE_WARN.
Mar 07, 2007: libarchive 2.0.21 released
Mar 07, 2007: Add some ACL tests (only for the system-independent
portion of the ACL support for now).
Mar 07, 2007: tar's ability to read ACLs off disk got
turned off for FreeBSD; re-enable it. (ACL restores and
libarchive support for storing/reading ACLs from pax
archives was unaffected.)
Mar 02, 2007: libarchive 2.0.20 released
Mar 2, 2007: It's not perfect, but it's pretty good.
Libarchive 2.0 is officially out of beta.
Feb 28, 2007: libarchive 2.0b17 released
Feb 27, 2007: Make the GID restore checks more robust by checking
whether the current user has too few or too many privileges.
Feb 26, 2007: libarchive 2.0b15 released
Feb 26, 2007: Don't lose symlinks when extracting from ISOs.
Thanks to Diego "Flameeyes" Pettenò for telling me about the
broken testcase on Gentoo that (finally!) led me to the cause
of this long-standing bug.
Feb 26, 2007: libarchive 2.0b14 released
Feb 26, 2007: Fix a broken test on platforms that lack lchmod().
Feb 25, 2007: libarchive 2.0b13 released
Feb 25, 2007: Empty archives were being written as empty files,
without a proper end-of-archive marker. Fixed.
Feb 23, 2007: libarchive 2.0b12 released
Feb 22, 2007: Basic security checks added: _EXTRACT_SECURE_NODOTDOT
and _EXTRACT_SECURE_SYMLINK. These checks used to be in bsdtar,
but they belong down in libarchive where they can be used by
other tools and where they can be better optimized.
Feb 11, 2007: libarchive 2.0b11 released
Feb 10, 2007: Fixed a bunch of errors in libarchive's handling
of EXTRACT_PERM and EXTRACT_OWNER, especially relating
to SUID and SGID bits.
Jan 31, 2007: libarchive 2.0b9 released
Jan 31, 2007: Added read support for "empty" archives as a
distinct archive format. Bsdtar uses this to handle, e.g.,
"touch foo.tar; tar -rf foo.tar"
Jan 22, 2007: libarchive 2.0b6 released
Jan 22, 2007: archive_write_disk API is now in place. It provides
a finer-grained interface than archive_read_extract. In particular,
you can use it to create objects on disk without having an archive
around (just feed it archive_entry objects describing what you
want to create), you can override the uname/gname-to-uid/gid lookups
(minitar uses this to avoid getpwXXX() and getgrXXX() bloat).
Jan 09, 2007: libarchive 2.0a3 released
Jan 9, 2007: archive_extract is now much better; it handles the
most common cases with a minimal number of system calls.
Some features still need a lot of testing, especially corner
cases involving objects that already exist on disk. I expect
the next round of API overhaul will simplify building test cases.
Jan 9, 2007: a number of fixes thanks to Colin Percival, especially
corrections to the skip() framework and handling of large files.
Jan 9, 2007: Fixes for large ISOs. The code should correctly handle
very large ISOs with entries up to 4G. Thanks to Robert Sciuk
for pointing out these issues.
Sep 05, 2006: libarchive 1.3.1 released
Sep 5, 2006: Bump version to 1.3 for new I/O wrappers.
Sep 4, 2006: New memory and FILE read/write wrappers.
Sep 4, 2006: libarchive test harness is now minimally functional;
it's located a few minor bugs in error-handling logic
Aug 17, 2006: libarchive 1.2.54 released
Aug 17, 2006: Outline ABI changes for libarchive 2.0; these
are protected behind #ifdef's until I think I've found everything
that needs to change.
Aug 17, 2006: Fix error-handling in archive_read/write_close()
They weren't returning any errors before.
Aug 17, 2006: Fix recursive-add logic to not trigger if it's not set
Fixes a bug adding files when writing archive to pipe or when
using archive_write_open() directly.
Jul 2006: New "skip" handling improves performance extracting
single files from large uncompressed archives.
Mar 21, 2006: 1.2.52 released
Mar 21, 2006: Fix -p on platforms that don't have platform-specific
extended attribute code.
Mar 20, 2006: Add NEWS file; fill in some older history from other
files. I'll try to keep this file up-to-date from now on.
OLDER NEWS SUMMARIES
Mar 19, 2006: libarchive 1.2.51 released
Mar 18, 2006: Many fixes to extended attribute support, including a redesign
of the storage format to simplify debugging.
Mar 12, 2006: Remove 'tp' support; it was a fun idea, but not worth
spending much time on.
Mar 11, 2006: Incorporated Jaakko Heinonen's still-experimental support
for extended attributes (Currently Linux-only.).
Mar 11, 2006: Reorganized distribution package: There is now one tar.gz
file that builds both libarchive and bsdtar.
Feb 13, 2006: Minor bug fixes: correctly read cpio device entries, write
Pax attribute entry names.
Nov 7, 2005: Experimental 'tp' format support in libarchive. Feedback
appreciated; this is not enabled by archive_read_support_format_all()
yet as I'm not quite content with the format detection heuristics.
Nov 7, 2005: Some more portability improvements thanks to Darin Broady,
minor bugfixes.
Oct 12, 2005: Use GNU libtool to build shared libraries on many systems.
Aug 9, 2005: Correctly detect that MacOS X does not have POSIX ACLs.
Apr 17, 2005: Kees Zeelenberg has ported libarchive and bsdtar to Windows:
http://gnuwin32.sourceforge.net/
Apr 11, 2005: Extended Zip/Zip64 support thanks to Dan Nelson. -L/-h
fix from Jaakko Heinonen.
Mar 12, 2005: archive_read_extract can now handle very long
pathnames (I've tested with pathnames up to 1MB).
Mar 12, 2005: Marcus Geiger has written an article about libarchive
http://xsnil.antbear.org/2005/02/05/archive-mit-libarchive-verarbeiten/
including examples of using it from Objective-C. His MoinX
http://moinx.antbear.org/ desktop Wiki uses
libarchive for archiving and restoring Wiki pages.
Jan 22, 2005: Preliminary ZIP extraction support,
new directory-walking code for bsdtar.
Jan 16, 2005: ISO9660 extraction code added; manpage corrections.
May 22, 2004: Many gtar-compatible long options have been added; almost
all FreeBSD ports extract correctly with bsdtar.
May 18, 2004: bsdtar can read Solaris, HP-UX, Unixware, star, gtar,
and pdtar archives.

View file

@ -0,0 +1,155 @@
README for libarchive bundle.
Questions? Issues?
* http://www.libarchive.org is the home for ongoing
libarchive development, including documentation, and
links to the libarchive mailing lists.
* To report an issue, use the issue tracker at
http://code.google.com/p/libarchive/issues/list
* To submit an enhancement to libarchive, please submit
a pull request via GitHub.
https://github.com/libarchive/libarchive/pulls
This distribution bundle includes the following components:
* libarchive: a library for reading and writing streaming archives
* tar: the 'bsdtar' program is a full-featured 'tar'
replacement built on libarchive
* cpio: the 'bsdcpio' program is a different interface to
essentially the same functionality
* examples: Some small example programs that you may find useful.
* examples/minitar: a compact sample demonstrating use of libarchive.
* contrib: Various items sent to me by third parties;
please contact the authors with any questions.
The top-level directory contains the following information files:
* NEWS - highlights of recent changes
* COPYING - what you can do with this
* INSTALL - installation instructions
* README - this file
* configure - configuration script, see INSTALL for details.
* CMakeLists.txt - input for "cmake" build tool, see INSTALL
The following files in the top-level directory are used by the
'configure' script:
* Makefile.am, aclocal.m4, configure.ac
- used to build this distribution, only needed by maintainers
* Makefile.in, config.h.in
- templates used by configure script
Guide to Documentation installed by this system:
* bsdtar.1 explains the use of the bsdtar program
* bsdcpio.1 explains the use of the bsdcpio program
* libarchive.3 gives an overview of the library as a whole
* archive_read.3, archive_write.3, archive_write_disk.3, and
archive_read_disk.3 provide detailed calling sequences for the read
and write APIs
* archive_entry.3 details the "struct archive_entry" utility class
* archive_internals.3 provides some insight into libarchive's
internal structure and operation.
* libarchive-formats.5 documents the file formats supported by the library
* cpio.5, mtree.5, and tar.5 provide detailed information about these
popular archive formats, including hard-to-find details about
modern cpio and tar variants.
The manual pages above are provided in the 'doc' directory in
a number of different formats.
You should also read the copious comments in "archive.h" and the
source code for the sample programs for more details. Please let us
know about any errors or omissions you find.
Currently, the library automatically detects and reads the following fomats:
* GNU tar format (including GNU long filenames, long link names, and sparse files)
* Solaris 9 extended tar format (including ACLs)
* Old V7 tar archives
* POSIX ustar
* POSIX pax interchange format
* POSIX octet-oriented cpio
* SVR4 ASCII cpio
* POSIX octet-oriented cpio
* Binary cpio (big-endian or little-endian)
* ISO9660 CD-ROM images (with optional Rockridge or Joliet extensions)
* ZIP archives (with uncompressed or "deflate" compressed entries)
* GNU and BSD 'ar' archives
* 'mtree' format
* 7-Zip archives
* Microsoft CAB format
* LHA and LZH archives
* RAR archives
* XAR archives
The library also detects and handles any of the following before evaluating the archive:
* uuencoded files
* files with RPM wrapper
* gzip compression
* bzip2 compression
* compress/LZW compression
* lzma, lzip, and xz compression
The library can create archives in any of the following formats:
* POSIX ustar
* POSIX pax interchange format
* "restricted" pax format, which will create ustar archives except for
entries that require pax extensions (for long filenames, ACLs, etc).
* Old GNU tar format
* POSIX octet-oriented cpio
* SVR4 "newc" cpio
* shar archives
* ZIP archives (with uncompressed or "deflate" compressed entries)
* GNU and BSD 'ar' archives
* 'mtree' format
* ISO9660 format
* 7-Zip archives
* XAR archives
When creating archives, the result can be filtered with any of the following:
* uuencode
* gzip compression
* bzip2 compression
* compress/LZW compression
* lzma, lzip, and xz compression
Notes about the library architecture:
* This is a heavily stream-oriented system. There is no direct
support for in-place modification or random access.
* The library is designed to be extended with new compression and
archive formats. The only requirement is that the format be
readable or writable as a stream and that each archive entry be
independent. There are articles on the libarchive Wiki explaining
how to extend libarchive.
* On read, compression and format are always detected automatically.
* I've attempted to minimize static link pollution. If you don't
explicitly invoke a particular feature (such as support for a
particular compression or format), it won't get pulled in.
In particular, if you don't explicitly enable a particular
compression or decompression support, you won't need to link
against the corresponding compression or decompression libraries.
This also reduces the size of statically-linked binaries in
environments where that matters.
* On read, the library accepts whatever blocks you hand it.
Your read callback is free to pass the library a byte at a time
or mmap the entire archive and give it to the library at once.
On write, the library always produces correctly-blocked output.
* The object-style approach allows you to have multiple archive streams
open at once. bsdtar uses this in its "@archive" extension.
* The archive itself is read/written using callback functions.
You can read an archive directly from an in-memory buffer or
write it to a socket, if you wish. There are some utility
functions to provide easy-to-use "open file," etc, capabilities.
* The read/write APIs are designed to allow individual entries
to be read or written to any data source: You can create
a block of data in memory and add it to a tar archive without
first writing a temporary file. You can also read an entry from
an archive and write the data directly to a socket. If you want
to read/write entries to disk, there are convenience functions to
make this especially easy.
* Note: "pax interchange format" is really an extended tar format,
despite what the name says.

9657
archive/libarchive-3.1.2/aclocal.m4 vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,51 @@
# AC_LANG_STDCALL_FUNC_LINK_TRY(FUNCTION, SIGNATURE)
# -------------------------------
# Produce a source which links correctly iff the FUNCTION exists.
AC_DEFUN([AC_LANG_STDCALL_FUNC_LINK_TRY],
[_AC_LANG_DISPATCH([$0], _AC_LANG, $@)])
# AC_CHECK_STDCALL_FUNC(FUNCTION, SIGNATURE, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
# -----------------------------------------------------------------
AC_DEFUN([AC_CHECK_STDCALL_FUNC],
[AS_VAR_PUSHDEF([ac_var], [ac_cv_func_$1])dnl
AC_CACHE_CHECK([for $1], ac_var,
[AC_LINK_IFELSE([AC_LANG_STDCALL_FUNC_LINK_TRY([$1],[$2])],
[AS_VAR_SET(ac_var, yes)],
[AS_VAR_SET(ac_var, no)])])
AS_IF([test AS_VAR_GET(ac_var) = yes], [$3], [$4])dnl
AS_VAR_POPDEF([ac_var])dnl
])# AC_CHECK_FUNC
# AC_LANG_STDCALL_FUNC_LINK_TRY(C)(FUNCTION, SIGNATURE)
# ----------------------------------
# Don't include <ctype.h> because on OSF/1 3.0 it includes
# <sys/types.h> which includes <sys/select.h> which contains a
# prototype for select. Similarly for bzero.
m4_define([AC_LANG_STDCALL_FUNC_LINK_TRY(C)],
[AC_LANG_PROGRAM(
[/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char __stdcall $1 ( $2 ) below. */
#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char __stdcall $1 ( $2 );
char (*f) ( $2 );
],
[/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_$1) || defined (__stub___$1)
choke me
#else
f = $1;
#endif
])])
# AC_LANG_STDCALL_FUNC_LINK_TRY(C++)(FUNCTION)
# ------------------------------------
m4_copy([AC_LANG_STDCALL_FUNC_LINK_TRY(C)], [AC_LANG_STDCALL_FUNC_LINK_TRY(C++)])

View file

@ -0,0 +1,343 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
scriptversion=2012-03-05.13; # UTC
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009, 2010, 2012 Free
# Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
nl='
'
# We need space, tab and new line, in precisely that order. Quoting is
# there to prevent tools from complaining about whitespace usage.
IFS=" "" $nl"
file_conv=
# func_file_conv build_file lazy
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts. If the determined conversion
# type is listed in (the comma separated) LAZY, no conversion will
# take place.
func_file_conv ()
{
file=$1
case $file in
/ | /[!/]*) # absolute file, and not a UNC file
if test -z "$file_conv"; then
# lazily determine how to convert abs files
case `uname -s` in
MINGW*)
file_conv=mingw
;;
CYGWIN*)
file_conv=cygwin
;;
*)
file_conv=wine
;;
esac
fi
case $file_conv/,$2, in
*,$file_conv,*)
;;
mingw/*)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin/*)
file=`cygpath -m "$file" || echo "$file"`
;;
wine/*)
file=`winepath -w "$file" || echo "$file"`
;;
esac
;;
esac
}
# func_cl_dashL linkdir
# Make cl look for libraries in LINKDIR
func_cl_dashL ()
{
func_file_conv "$1"
if test -z "$lib_path"; then
lib_path=$file
else
lib_path="$lib_path;$file"
fi
linker_opts="$linker_opts -LIBPATH:$file"
}
# func_cl_dashl library
# Do a library search-path lookup for cl
func_cl_dashl ()
{
lib=$1
found=no
save_IFS=$IFS
IFS=';'
for dir in $lib_path $LIB
do
IFS=$save_IFS
if $shared && test -f "$dir/$lib.dll.lib"; then
found=yes
lib=$dir/$lib.dll.lib
break
fi
if test -f "$dir/$lib.lib"; then
found=yes
lib=$dir/$lib.lib
break
fi
done
IFS=$save_IFS
if test "$found" != yes; then
lib=$lib.lib
fi
}
# func_cl_wrapper cl arg...
# Adjust compile command to suit cl
func_cl_wrapper ()
{
# Assume a capable shell
lib_path=
shared=:
linker_opts=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
eat=1
case $2 in
*.o | *.[oO][bB][jJ])
func_file_conv "$2"
set x "$@" -Fo"$file"
shift
;;
*)
func_file_conv "$2"
set x "$@" -Fe"$file"
shift
;;
esac
;;
-I)
eat=1
func_file_conv "$2" mingw
set x "$@" -I"$file"
shift
;;
-I*)
func_file_conv "${1#-I}" mingw
set x "$@" -I"$file"
shift
;;
-l)
eat=1
func_cl_dashl "$2"
set x "$@" "$lib"
shift
;;
-l*)
func_cl_dashl "${1#-l}"
set x "$@" "$lib"
shift
;;
-L)
eat=1
func_cl_dashL "$2"
;;
-L*)
func_cl_dashL "${1#-L}"
;;
-static)
shared=false
;;
-Wl,*)
arg=${1#-Wl,}
save_ifs="$IFS"; IFS=','
for flag in $arg; do
IFS="$save_ifs"
linker_opts="$linker_opts $flag"
done
IFS="$save_ifs"
;;
-Xlinker)
eat=1
linker_opts="$linker_opts $2"
;;
-*)
set x "$@" "$1"
shift
;;
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
func_file_conv "$1"
set x "$@" -Tp"$file"
shift
;;
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
func_file_conv "$1" mingw
set x "$@" "$file"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -n "$linker_opts"; then
linker_opts="-link$linker_opts"
fi
exec "$@" $linker_opts
exit 1
}
eat=
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand '-c -o'.
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file 'INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "compile $scriptversion"
exit $?
;;
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
ofile=
cfile=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
# So we strip '-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no '-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# '.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi
# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
# Create the lock directory.
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
while true; do
if mkdir "$lockdir" >/dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15
# Run the compile.
"$@"
ret=$?
if test -f "$cofile"; then
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
fi
rmdir "$lockdir"
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,696 @@
#! /bin/sh
#
# NOTE: This file was brought from
# http://git.savannah.gnu.org/cgit/gnulib.git/plain/build-aux/config.rpath
# You should sometimes check if the file is updated and bring it to
# our trunk and copy this note to the top of that file.
#
# Output a system dependent set of variables, describing how to set the
# run time search path of shared libraries in an executable.
#
# Copyright 1996-2011 Free Software Foundation, Inc.
# Taken from GNU libtool, 2001
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# The first argument passed to this file is the canonical host specification,
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
# or
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
# should be set by the caller.
#
# The set of defined variables is at the end of this script.
# Known limitations:
# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
# than 256 bytes, otherwise the compiler driver will dump core. The only
# known workaround is to choose shorter directory names for the build
# directory and/or the installation directory.
# All known linkers require a `.a' archive for static linking (except MSVC,
# which needs '.lib').
libext=a
shrext=.so
host="$1"
host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
# Code taken from libtool.m4's _LT_CC_BASENAME.
for cc_temp in $CC""; do
case $cc_temp in
compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
\-*) ;;
*) break;;
esac
done
cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
# Code taken from libtool.m4's _LT_COMPILER_PIC.
wl=
if test "$GCC" = yes; then
wl='-Wl,'
else
case "$host_os" in
aix*)
wl='-Wl,'
;;
mingw* | cygwin* | pw32* | os2* | cegcc*)
;;
hpux9* | hpux10* | hpux11*)
wl='-Wl,'
;;
irix5* | irix6* | nonstopux*)
wl='-Wl,'
;;
linux* | k*bsd*-gnu | kopensolaris*-gnu)
case $cc_basename in
ecc*)
wl='-Wl,'
;;
icc* | ifort*)
wl='-Wl,'
;;
lf95*)
wl='-Wl,'
;;
nagfor*)
wl='-Wl,-Wl,,'
;;
pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
wl='-Wl,'
;;
ccc*)
wl='-Wl,'
;;
xl* | bgxl* | bgf* | mpixl*)
wl='-Wl,'
;;
como)
wl='-lopt='
;;
*)
case `$CC -V 2>&1 | sed 5q` in
*Sun\ F* | *Sun*Fortran*)
wl=
;;
*Sun\ C*)
wl='-Wl,'
;;
esac
;;
esac
;;
newsos6)
;;
*nto* | *qnx*)
;;
osf3* | osf4* | osf5*)
wl='-Wl,'
;;
rdos*)
;;
solaris*)
case $cc_basename in
f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
wl='-Qoption ld '
;;
*)
wl='-Wl,'
;;
esac
;;
sunos4*)
wl='-Qoption ld '
;;
sysv4 | sysv4.2uw2* | sysv4.3*)
wl='-Wl,'
;;
sysv4*MP*)
;;
sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
wl='-Wl,'
;;
unicos*)
wl='-Wl,'
;;
uts4*)
;;
esac
fi
# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
hardcode_libdir_flag_spec=
hardcode_libdir_separator=
hardcode_direct=no
hardcode_minus_L=no
case "$host_os" in
cygwin* | mingw* | pw32* | cegcc*)
# FIXME: the MSVC++ port hasn't been tested in a loooong time
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
if test "$GCC" != yes; then
with_gnu_ld=no
fi
;;
interix*)
# we just hope/assume this is gcc and not c89 (= MSVC++)
with_gnu_ld=yes
;;
openbsd*)
with_gnu_ld=no
;;
esac
ld_shlibs=yes
if test "$with_gnu_ld" = yes; then
# Set some defaults for GNU ld with shared library support. These
# are reset later if shared libraries are not supported. Putting them
# here allows them to be overridden if necessary.
# Unlike libtool, we use -rpath here, not --rpath, since the documented
# option of GNU ld is called -rpath, not --rpath.
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
case "$host_os" in
aix[3-9]*)
# On AIX/PPC, the GNU linker is very broken
if test "$host_cpu" != ia64; then
ld_shlibs=no
fi
;;
amigaos*)
case "$host_cpu" in
powerpc)
;;
m68k)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
;;
esac
;;
beos*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
cygwin* | mingw* | pw32* | cegcc*)
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
hardcode_libdir_flag_spec='-L$libdir'
if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
haiku*)
;;
interix[3-9]*)
hardcode_direct=no
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
netbsd*)
;;
solaris*)
if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
ld_shlibs=no
elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
case `$LD -v 2>&1` in
*\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
ld_shlibs=no
;;
*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
else
ld_shlibs=no
fi
;;
esac
;;
sunos4*)
hardcode_direct=yes
;;
*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
esac
if test "$ld_shlibs" = no; then
hardcode_libdir_flag_spec=
fi
else
case "$host_os" in
aix3*)
# Note: this linker hardcodes the directories in LIBPATH if there
# are no directories specified by -L.
hardcode_minus_L=yes
if test "$GCC" = yes; then
# Neither direct hardcoding nor static linking is supported with a
# broken collect2.
hardcode_direct=unsupported
fi
;;
aix[4-9]*)
if test "$host_cpu" = ia64; then
# On IA64, the linker does run time linking by default, so we don't
# have to do anything special.
aix_use_runtimelinking=no
else
aix_use_runtimelinking=no
# Test if we are trying to use run time linking or normal
# AIX style linking. If -brtl is somewhere in LDFLAGS, we
# need to do runtime linking.
case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
for ld_flag in $LDFLAGS; do
if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
aix_use_runtimelinking=yes
break
fi
done
;;
esac
fi
hardcode_direct=yes
hardcode_libdir_separator=':'
if test "$GCC" = yes; then
case $host_os in aix4.[012]|aix4.[012].*)
collect2name=`${CC} -print-prog-name=collect2`
if test -f "$collect2name" && \
strings "$collect2name" | grep resolve_lib_name >/dev/null
then
# We have reworked collect2
:
else
# We have old collect2
hardcode_direct=unsupported
hardcode_minus_L=yes
hardcode_libdir_flag_spec='-L$libdir'
hardcode_libdir_separator=
fi
;;
esac
fi
# Begin _LT_AC_SYS_LIBPATH_AIX.
echo 'int main () { return 0; }' > conftest.c
${CC} ${LDFLAGS} conftest.c -o conftest
aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
}'`
if test -z "$aix_libpath"; then
aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
}'`
fi
if test -z "$aix_libpath"; then
aix_libpath="/usr/lib:/lib"
fi
rm -f conftest.c conftest
# End _LT_AC_SYS_LIBPATH_AIX.
if test "$aix_use_runtimelinking" = yes; then
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
else
if test "$host_cpu" = ia64; then
hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
else
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
fi
fi
;;
amigaos*)
case "$host_cpu" in
powerpc)
;;
m68k)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
;;
esac
;;
bsdi[45]*)
;;
cygwin* | mingw* | pw32* | cegcc*)
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
hardcode_libdir_flag_spec=' '
libext=lib
;;
darwin* | rhapsody*)
hardcode_direct=no
if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then
:
else
ld_shlibs=no
fi
;;
dgux*)
hardcode_libdir_flag_spec='-L$libdir'
;;
freebsd2.2*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
freebsd2*)
hardcode_direct=yes
hardcode_minus_L=yes
;;
freebsd* | dragonfly*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
hpux9*)
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
;;
hpux10*)
if test "$with_gnu_ld" = no; then
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
fi
;;
hpux11*)
if test "$with_gnu_ld" = no; then
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
case $host_cpu in
hppa*64*|ia64*)
hardcode_direct=no
;;
*)
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
;;
esac
fi
;;
irix5* | irix6* | nonstopux*)
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
netbsd*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
newsos6)
hardcode_direct=yes
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
*nto* | *qnx*)
;;
openbsd*)
if test -f /usr/libexec/ld.so; then
hardcode_direct=yes
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
else
case "$host_os" in
openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
hardcode_libdir_flag_spec='-R$libdir'
;;
*)
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
esac
fi
else
ld_shlibs=no
fi
;;
os2*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
;;
osf3*)
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
osf4* | osf5*)
if test "$GCC" = yes; then
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
else
# Both cc and cxx compiler support -rpath directly
hardcode_libdir_flag_spec='-rpath $libdir'
fi
hardcode_libdir_separator=:
;;
solaris*)
hardcode_libdir_flag_spec='-R$libdir'
;;
sunos4*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_direct=yes
hardcode_minus_L=yes
;;
sysv4)
case $host_vendor in
sni)
hardcode_direct=yes # is this really true???
;;
siemens)
hardcode_direct=no
;;
motorola)
hardcode_direct=no #Motorola manual says yes, but my tests say they lie
;;
esac
;;
sysv4.3*)
;;
sysv4*MP*)
if test -d /usr/nec; then
ld_shlibs=yes
fi
;;
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
;;
sysv5* | sco3.2v5* | sco5v6*)
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
hardcode_libdir_separator=':'
;;
uts4*)
hardcode_libdir_flag_spec='-L$libdir'
;;
*)
ld_shlibs=no
;;
esac
fi
# Check dynamic linker characteristics
# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
# Unlike libtool.m4, here we don't care about _all_ names of the library, but
# only about the one the linker finds when passed -lNAME. This is the last
# element of library_names_spec in libtool.m4, or possibly two of them if the
# linker has special search rules.
library_names_spec= # the last element of library_names_spec in libtool.m4
libname_spec='lib$name'
case "$host_os" in
aix3*)
library_names_spec='$libname.a'
;;
aix[4-9]*)
library_names_spec='$libname$shrext'
;;
amigaos*)
case "$host_cpu" in
powerpc*)
library_names_spec='$libname$shrext' ;;
m68k)
library_names_spec='$libname.a' ;;
esac
;;
beos*)
library_names_spec='$libname$shrext'
;;
bsdi[45]*)
library_names_spec='$libname$shrext'
;;
cygwin* | mingw* | pw32* | cegcc*)
shrext=.dll
library_names_spec='$libname.dll.a $libname.lib'
;;
darwin* | rhapsody*)
shrext=.dylib
library_names_spec='$libname$shrext'
;;
dgux*)
library_names_spec='$libname$shrext'
;;
freebsd* | dragonfly*)
case "$host_os" in
freebsd[123]*)
library_names_spec='$libname$shrext$versuffix' ;;
*)
library_names_spec='$libname$shrext' ;;
esac
;;
gnu*)
library_names_spec='$libname$shrext'
;;
haiku*)
library_names_spec='$libname$shrext'
;;
hpux9* | hpux10* | hpux11*)
case $host_cpu in
ia64*)
shrext=.so
;;
hppa*64*)
shrext=.sl
;;
*)
shrext=.sl
;;
esac
library_names_spec='$libname$shrext'
;;
interix[3-9]*)
library_names_spec='$libname$shrext'
;;
irix5* | irix6* | nonstopux*)
library_names_spec='$libname$shrext'
case "$host_os" in
irix5* | nonstopux*)
libsuff= shlibsuff=
;;
*)
case $LD in
*-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
*-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
*-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
*) libsuff= shlibsuff= ;;
esac
;;
esac
;;
linux*oldld* | linux*aout* | linux*coff*)
;;
linux* | k*bsd*-gnu | kopensolaris*-gnu)
library_names_spec='$libname$shrext'
;;
knetbsd*-gnu)
library_names_spec='$libname$shrext'
;;
netbsd*)
library_names_spec='$libname$shrext'
;;
newsos6)
library_names_spec='$libname$shrext'
;;
*nto* | *qnx*)
library_names_spec='$libname$shrext'
;;
openbsd*)
library_names_spec='$libname$shrext$versuffix'
;;
os2*)
libname_spec='$name'
shrext=.dll
library_names_spec='$libname.a'
;;
osf3* | osf4* | osf5*)
library_names_spec='$libname$shrext'
;;
rdos*)
;;
solaris*)
library_names_spec='$libname$shrext'
;;
sunos4*)
library_names_spec='$libname$shrext$versuffix'
;;
sysv4 | sysv4.3*)
library_names_spec='$libname$shrext'
;;
sysv4*MP*)
library_names_spec='$libname$shrext'
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
library_names_spec='$libname$shrext'
;;
tpf*)
library_names_spec='$libname$shrext'
;;
uts4*)
library_names_spec='$libname$shrext'
;;
esac
sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
# How to pass a linker flag through the compiler.
wl="$escaped_wl"
# Static library suffix (normally "a").
libext="$libext"
# Shared library suffix (normally "so").
shlibext="$shlibext"
# Format of library name prefix.
libname_spec="$escaped_libname_spec"
# Library names that the linker finds when passed -lNAME.
library_names_spec="$escaped_library_names_spec"
# Flag to hardcode \$libdir into a binary during linking.
# This must work even if \$libdir does not exist.
hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
# Whether we need a single -rpath flag with a separated argument.
hardcode_libdir_separator="$hardcode_libdir_separator"
# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
# resulting binary.
hardcode_direct="$hardcode_direct"
# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
# resulting binary.
hardcode_minus_L="$hardcode_minus_L"
EOF

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,708 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2012-03-27.16; # UTC
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010,
# 2011, 2012 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program 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 General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by 'PROGRAMS ARGS'.
object Object file output by 'PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
# A tabulation character.
tab=' '
# A newline character.
nl='
'
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvisualcpp
fi
if test "$depmode" = msvc7msys; then
# This is just like msvc7 but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvc7
fi
if test "$depmode" = xlc; then
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations.
gccflag=-qmakedep=gcc,-MF
depmode=gcc
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the "deleted header file" problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' "$nl" < "$tmpdepfile" |
## Some versions of gcc put a space before the ':'. On the theory
## that the space means something, we add a space to the output as
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like '#:fec' to the end of the
# dependency line.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr "$nl" ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
xlc)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts '$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
tmpdepfile1=$dir$base.u
tmpdepfile2=$dir$base.u
tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
# Each line is of the form 'foo.o: dependent.h'.
# Do two passes, one to just change these to
# '$object: dependent.h' and one to simply 'dependent.h:'.
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
icc)
# Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'.
# However on
# $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using '\':
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
# tcc 0.9.26 (FIXME still under development at the moment of writing)
# will emit a similar output, but also prepend the continuation lines
# with horizontal tabulation characters.
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form 'foo.o: dependent.h',
# or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'.
# Do two passes, one to just change these to
# '$object: dependent.h' and one to simply 'dependent.h:'.
sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \
< "$tmpdepfile" > "$depfile"
sed '
s/[ '"$tab"'][ '"$tab"']*/ /g
s/^ *//
s/ *\\*$//
s/^[^:]*: *//
/^$/d
/:$/d
s/$/ :/
' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
# Add 'dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
s/$/:/
p
}' "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in 'foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
# With Tru64 cc, shared objects can also be used to make a
# static library. This mechanism is used in libtool 1.4 series to
# handle both shared and static libraries in a single compilation.
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
#
# With libtool 1.5 this exception was removed, and libtool now
# generates 2 separate objects for the 2 libraries. These two
# compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
tmpdepfile2=$dir$base.o.d # libtool 1.5
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.o.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
tmpdepfile4=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
msvc7)
if test "$libtool" = yes; then
showIncludes=-Wc,-showIncludes
else
showIncludes=-showIncludes
fi
"$@" $showIncludes > "$tmpdepfile"
stat=$?
grep -v '^Note: including file: ' "$tmpdepfile"
if test "$stat" = 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The first sed program below extracts the file names and escapes
# backslashes for cygpath. The second sed program outputs the file
# name when reading, but also accumulates all include files in the
# hold buffer in order to output them again at the end. This only
# works with sed implementations that can handle large buffers.
sed < "$tmpdepfile" -n '
/^Note: including file: *\(.*\)/ {
s//\1/
s/\\/\\\\/g
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
s/\(.*\)/'"$tab"'\1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
s/.*/'"$tab"'/
G
p
}' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvc7msys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for ':'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' "$nl" < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no eat=no
for arg
do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
if test $eat = yes; then
eat=no
continue
fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-arch)
eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E |
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
IFS=" "
for arg
do
case "$arg" in
-o)
shift
;;
$object)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E 2>/dev/null |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
echo "$tab" >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvcmsys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

View file

@ -0,0 +1,268 @@
# iconv.m4 serial 18 (gettext-0.18.2)
dnl Copyright (C) 2000-2002, 2007-2011 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Bruno Haible.
AC_DEFUN([AM_ICONV_LINKFLAGS_BODY],
[
dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
AC_REQUIRE([AC_LIB_RPATH])
dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
dnl accordingly.
AC_LIB_LINKFLAGS_BODY([iconv])
])
AC_DEFUN([AM_ICONV_LINK],
[
dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
dnl those with the standalone portable GNU libiconv installed).
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
dnl accordingly.
AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
dnl Add $INCICONV to CPPFLAGS before performing the following checks,
dnl because if the user has installed libiconv and not disabled its use
dnl via --without-libiconv-prefix, he wants to use it. The first
dnl AC_LINK_IFELSE will then fail, the second AC_LINK_IFELSE will succeed.
am_save_CPPFLAGS="$CPPFLAGS"
AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV])
AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [
am_cv_func_iconv="no, consider installing GNU libiconv"
am_cv_lib_iconv=no
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[
#include <stdlib.h>
#include <iconv.h>
]],
[[iconv_t cd = iconv_open("","");
iconv(cd,NULL,NULL,NULL,NULL);
iconv_close(cd);]])],
[am_cv_func_iconv=yes])
if test "$am_cv_func_iconv" != yes; then
am_save_LIBS="$LIBS"
LIBS="$LIBS $LIBICONV"
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[
#include <stdlib.h>
#include <iconv.h>
]],
[[iconv_t cd = iconv_open("","");
iconv(cd,NULL,NULL,NULL,NULL);
iconv_close(cd);]])],
[am_cv_lib_iconv=yes]
[am_cv_func_iconv=yes])
LIBS="$am_save_LIBS"
fi
])
if test "$am_cv_func_iconv" = yes; then
AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [
dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11,
dnl Solaris 10.
am_save_LIBS="$LIBS"
if test $am_cv_lib_iconv = yes; then
LIBS="$LIBS $LIBICONV"
fi
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
#include <iconv.h>
#include <string.h>
int main ()
{
int result = 0;
/* Test against AIX 5.1 bug: Failures are not distinguishable from successful
returns. */
{
iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
if (cd_utf8_to_88591 != (iconv_t)(-1))
{
static const char input[] = "\342\202\254"; /* EURO SIGN */
char buf[10];
const char *inptr = input;
size_t inbytesleft = strlen (input);
char *outptr = buf;
size_t outbytesleft = sizeof (buf);
size_t res = iconv (cd_utf8_to_88591,
(char **) &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res == 0)
result |= 1;
iconv_close (cd_utf8_to_88591);
}
}
/* Test against Solaris 10 bug: Failures are not distinguishable from
successful returns. */
{
iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
if (cd_ascii_to_88591 != (iconv_t)(-1))
{
static const char input[] = "\263";
char buf[10];
const char *inptr = input;
size_t inbytesleft = strlen (input);
char *outptr = buf;
size_t outbytesleft = sizeof (buf);
size_t res = iconv (cd_ascii_to_88591,
(char **) &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res == 0)
result |= 2;
iconv_close (cd_ascii_to_88591);
}
}
/* Test against AIX 6.1..7.1 bug: Buffer overrun. */
{
iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1");
if (cd_88591_to_utf8 != (iconv_t)(-1))
{
static const char input[] = "\304";
static char buf[2] = { (char)0xDE, (char)0xAD };
const char *inptr = input;
size_t inbytesleft = 1;
char *outptr = buf;
size_t outbytesleft = 1;
size_t res = iconv (cd_88591_to_utf8,
(char **) &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD)
result |= 4;
iconv_close (cd_88591_to_utf8);
}
}
#if 0 /* This bug could be worked around by the caller. */
/* Test against HP-UX 11.11 bug: Positive return value instead of 0. */
{
iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
if (cd_88591_to_utf8 != (iconv_t)(-1))
{
static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
char buf[50];
const char *inptr = input;
size_t inbytesleft = strlen (input);
char *outptr = buf;
size_t outbytesleft = sizeof (buf);
size_t res = iconv (cd_88591_to_utf8,
(char **) &inptr, &inbytesleft,
&outptr, &outbytesleft);
if ((int)res > 0)
result |= 8;
iconv_close (cd_88591_to_utf8);
}
}
#endif
/* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
provided. */
if (/* Try standardized names. */
iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
/* Try IRIX, OSF/1 names. */
&& iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
/* Try AIX names. */
&& iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
/* Try HP-UX names. */
&& iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
result |= 16;
return result;
}]])],
[am_cv_func_iconv_works=yes],
[am_cv_func_iconv_works=no],
[
changequote(,)dnl
case "$host_os" in
aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
*) am_cv_func_iconv_works="guessing yes" ;;
esac
changequote([,])dnl
])
LIBS="$am_save_LIBS"
])
case "$am_cv_func_iconv_works" in
*no) am_func_iconv=no am_cv_lib_iconv=no ;;
*) am_func_iconv=yes ;;
esac
else
am_func_iconv=no am_cv_lib_iconv=no
fi
if test "$am_func_iconv" = yes; then
AC_DEFINE([HAVE_ICONV], [1],
[Define if you have the iconv() function and it works.])
fi
if test "$am_cv_lib_iconv" = yes; then
AC_MSG_CHECKING([how to link with libiconv])
AC_MSG_RESULT([$LIBICONV])
else
dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV
dnl either.
CPPFLAGS="$am_save_CPPFLAGS"
LIBICONV=
LTLIBICONV=
fi
AC_SUBST([LIBICONV])
AC_SUBST([LTLIBICONV])
])
dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to
dnl avoid warnings like
dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required".
dnl This is tricky because of the way 'aclocal' is implemented:
dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN.
dnl Otherwise aclocal's initial scan pass would miss the macro definition.
dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions.
dnl Otherwise aclocal would emit many "Use of uninitialized value $1"
dnl warnings.
m4_define([gl_iconv_AC_DEFUN],
m4_version_prereq([2.64],
[[AC_DEFUN_ONCE(
[$1], [$2])]],
[m4_ifdef([gl_00GNULIB],
[[AC_DEFUN_ONCE(
[$1], [$2])]],
[[AC_DEFUN(
[$1], [$2])]])]))
gl_iconv_AC_DEFUN([AM_ICONV],
[
AM_ICONV_LINK
if test "$am_cv_func_iconv" = yes; then
AC_MSG_CHECKING([for iconv declaration])
AC_CACHE_VAL([am_cv_proto_iconv], [
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[
#include <stdlib.h>
#include <iconv.h>
extern
#ifdef __cplusplus
"C"
#endif
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus)
size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
#else
size_t iconv();
#endif
]],
[[]])],
[am_cv_proto_iconv_arg1=""],
[am_cv_proto_iconv_arg1="const"])
am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
AC_MSG_RESULT([
$am_cv_proto_iconv])
AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1],
[Define as const if the declaration of iconv() needs const.])
dnl Also substitute ICONV_CONST in the gnulib generated <iconv.h>.
m4_ifdef([gl_ICONV_H_DEFAULTS],
[AC_REQUIRE([gl_ICONV_H_DEFAULTS])
if test -n "$am_cv_proto_iconv_arg1"; then
ICONV_CONST="const"
fi
])
fi
])

View file

@ -0,0 +1,527 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2011-01-19.21; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_glob='?'
initialize_posix_glob='
test "$posix_glob" != "?" || {
if (set -f) 2>/dev/null; then
posix_glob=
else
posix_glob=:
fi
}
'
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
no_target_directory=
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t) dst_arg=$2
# Protect names problematic for `test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) no_target_directory=true;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for `test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for `test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writeable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
$posix_glob set -f
set fnord $dstdir
shift
$posix_glob set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
eval "$initialize_posix_glob" &&
$posix_glob set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
$posix_glob set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

View file

@ -0,0 +1,20 @@
# la_TYPE_UID_T
# -------------
AC_DEFUN([la_TYPE_UID_T],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
AC_CACHE_CHECK(for uid_t in sys/types.h, la_cv_type_uid_t,
[AC_EGREP_HEADER(uid_t, sys/types.h,
la_cv_type_uid_t=yes, la_cv_type_uid_t=no)])
if test $la_cv_type_uid_t = no; then
case $host in
*mingw*) def_uid_t=short ;;
*) def_uid_t=int ;;
esac
AC_DEFINE_UNQUOTED(uid_t, [$def_uid_t],
[Define to match typeof st_uid field of struct stat if <sys/types.h> doesn't define.])
AC_DEFINE_UNQUOTED(gid_t, [$def_uid_t],
[Define to match typeof st_gid field of struct stat if <sys/types.h> doesn't define.])
fi
])
AU_ALIAS([AC_TYPE_UID_T], [la_TYPE_UID_T])

View file

@ -0,0 +1,109 @@
# lib-ld.m4 serial 5 (gettext-0.18.2)
dnl Copyright (C) 1996-2003, 2009-2011 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl Subroutines of libtool.m4,
dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision
dnl with libtool.m4.
dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no.
AC_DEFUN([AC_LIB_PROG_LD_GNU],
[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld],
[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
case `$LD -v 2>&1 </dev/null` in
*GNU* | *'with BFD'*)
acl_cv_prog_gnu_ld=yes ;;
*)
acl_cv_prog_gnu_ld=no ;;
esac])
with_gnu_ld=$acl_cv_prog_gnu_ld
])
dnl From libtool-1.4. Sets the variable LD.
AC_DEFUN([AC_LIB_PROG_LD],
[AC_ARG_WITH([gnu-ld],
[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_CANONICAL_HOST])dnl
# Prepare PATH_SEPARATOR.
# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
# Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which
# contains only /bin. Note that ksh looks also at the FPATH variable,
# so we have to set that as well for the test.
PATH_SEPARATOR=:
(PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
&& { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
|| PATH_SEPARATOR=';'
}
fi
ac_prog=ld
if test "$GCC" = yes; then
# Check if gcc -print-prog-name=ld gives a path.
AC_MSG_CHECKING([for ld used by GCC])
case $host in
*-*-mingw*)
# gcc leaves a trailing carriage return which upsets mingw
ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
*)
ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
esac
case $ac_prog in
# Accept absolute paths.
[[\\/]* | [A-Za-z]:[\\/]*)]
[re_direlt='/[^/][^/]*/\.\./']
# Canonicalize the path of ld
ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
done
test -z "$LD" && LD="$ac_prog"
;;
"")
# If it fails, then pretend we aren't using GCC.
ac_prog=ld
;;
*)
# If it is relative, then search for the first ld in PATH.
with_gnu_ld=unknown
;;
esac
elif test "$with_gnu_ld" = yes; then
AC_MSG_CHECKING([for GNU ld])
else
AC_MSG_CHECKING([for non-GNU ld])
fi
AC_CACHE_VAL([acl_cv_path_LD],
[if test -z "$LD"; then
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
for ac_dir in $PATH; do
test -z "$ac_dir" && ac_dir=.
if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
acl_cv_path_LD="$ac_dir/$ac_prog"
# Check to see if the program is GNU ld. I'd rather use --version,
# but apparently some GNU ld's only accept -v.
# Break only if it was the GNU/non-GNU ld that we prefer.
case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in
*GNU* | *'with BFD'*)
test "$with_gnu_ld" != no && break ;;
*)
test "$with_gnu_ld" != yes && break ;;
esac
fi
done
IFS="$ac_save_ifs"
else
acl_cv_path_LD="$LD" # Let the user override the test with a path.
fi])
LD="$acl_cv_path_LD"
if test -n "$LD"; then
AC_MSG_RESULT([$LD])
else
AC_MSG_RESULT([no])
fi
test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
AC_LIB_PROG_LD_GNU
])

View file

@ -0,0 +1,777 @@
# lib-link.m4 serial 26 (gettext-0.18.2)
dnl Copyright (C) 2001-2011 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Bruno Haible.
AC_PREREQ([2.54])
dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
dnl the libraries corresponding to explicit and implicit dependencies.
dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and
dnl augments the CPPFLAGS variable.
dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
AC_DEFUN([AC_LIB_LINKFLAGS],
[
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
AC_REQUIRE([AC_LIB_RPATH])
pushdef([Name],[m4_translit([$1],[./+-], [____])])
pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [
AC_LIB_LINKFLAGS_BODY([$1], [$2])
ac_cv_lib[]Name[]_libs="$LIB[]NAME"
ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME"
ac_cv_lib[]Name[]_cppflags="$INC[]NAME"
ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX"
])
LIB[]NAME="$ac_cv_lib[]Name[]_libs"
LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs"
INC[]NAME="$ac_cv_lib[]Name[]_cppflags"
LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix"
AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
AC_SUBST([LIB]NAME)
AC_SUBST([LTLIB]NAME)
AC_SUBST([LIB]NAME[_PREFIX])
dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the
dnl results of this search when this library appears as a dependency.
HAVE_LIB[]NAME=yes
popdef([NAME])
popdef([Name])
])
dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [missing-message])
dnl searches for libname and the libraries corresponding to explicit and
dnl implicit dependencies, together with the specified include files and
dnl the ability to compile and link the specified testcode. The missing-message
dnl defaults to 'no' and may contain additional hints for the user.
dnl If found, it sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME}
dnl and LTLIB${NAME} variables and augments the CPPFLAGS variable, and
dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs
dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty.
dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
[
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
AC_REQUIRE([AC_LIB_RPATH])
pushdef([Name],[m4_translit([$1],[./+-], [____])])
pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
dnl accordingly.
AC_LIB_LINKFLAGS_BODY([$1], [$2])
dnl Add $INC[]NAME to CPPFLAGS before performing the following checks,
dnl because if the user has installed lib[]Name and not disabled its use
dnl via --without-lib[]Name-prefix, he wants to use it.
ac_save_CPPFLAGS="$CPPFLAGS"
AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [
ac_save_LIBS="$LIBS"
dnl If $LIB[]NAME contains some -l options, add it to the end of LIBS,
dnl because these -l options might require -L options that are present in
dnl LIBS. -l options benefit only from the -L options listed before it.
dnl Otherwise, add it to the front of LIBS, because it may be a static
dnl library that depends on another static library that is present in LIBS.
dnl Static libraries benefit only from the static libraries listed after
dnl it.
case " $LIB[]NAME" in
*" -l"*) LIBS="$LIBS $LIB[]NAME" ;;
*) LIBS="$LIB[]NAME $LIBS" ;;
esac
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[$3]], [[$4]])],
[ac_cv_lib[]Name=yes],
[ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])'])
LIBS="$ac_save_LIBS"
])
if test "$ac_cv_lib[]Name" = yes; then
HAVE_LIB[]NAME=yes
AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib][$1 library.])
AC_MSG_CHECKING([how to link with lib[]$1])
AC_MSG_RESULT([$LIB[]NAME])
else
HAVE_LIB[]NAME=no
dnl If $LIB[]NAME didn't lead to a usable library, we don't need
dnl $INC[]NAME either.
CPPFLAGS="$ac_save_CPPFLAGS"
LIB[]NAME=
LTLIB[]NAME=
LIB[]NAME[]_PREFIX=
fi
AC_SUBST([HAVE_LIB]NAME)
AC_SUBST([LIB]NAME)
AC_SUBST([LTLIB]NAME)
AC_SUBST([LIB]NAME[_PREFIX])
popdef([NAME])
popdef([Name])
])
dnl Determine the platform dependent parameters needed to use rpath:
dnl acl_libext,
dnl acl_shlibext,
dnl acl_libname_spec,
dnl acl_library_names_spec,
dnl acl_hardcode_libdir_flag_spec,
dnl acl_hardcode_libdir_separator,
dnl acl_hardcode_direct,
dnl acl_hardcode_minus_L.
AC_DEFUN([AC_LIB_RPATH],
[
dnl Tell automake >= 1.10 to complain if config.rpath is missing.
m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])])
AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS
AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld
AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host
AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir
AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [
CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
. ./conftest.sh
rm -f ./conftest.sh
acl_cv_rpath=done
])
wl="$acl_cv_wl"
acl_libext="$acl_cv_libext"
acl_shlibext="$acl_cv_shlibext"
acl_libname_spec="$acl_cv_libname_spec"
acl_library_names_spec="$acl_cv_library_names_spec"
acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
acl_hardcode_direct="$acl_cv_hardcode_direct"
acl_hardcode_minus_L="$acl_cv_hardcode_minus_L"
dnl Determine whether the user wants rpath handling at all.
AC_ARG_ENABLE([rpath],
[ --disable-rpath do not hardcode runtime library paths],
:, enable_rpath=yes)
])
dnl AC_LIB_FROMPACKAGE(name, package)
dnl declares that libname comes from the given package. The configure file
dnl will then not have a --with-libname-prefix option but a
dnl --with-package-prefix option. Several libraries can come from the same
dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar
dnl macro call that searches for libname.
AC_DEFUN([AC_LIB_FROMPACKAGE],
[
pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
define([acl_frompackage_]NAME, [$2])
popdef([NAME])
pushdef([PACK],[$2])
pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
define([acl_libsinpackage_]PACKUP,
m4_ifdef([acl_libsinpackage_]PACKUP, [m4_defn([acl_libsinpackage_]PACKUP)[, ]],)[lib$1])
popdef([PACKUP])
popdef([PACK])
])
dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and
dnl the libraries corresponding to explicit and implicit dependencies.
dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables.
dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found
dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
[
AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])])
pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])])
dnl Autoconf >= 2.61 supports dots in --with options.
pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[m4_translit(PACK,[.],[_])],PACK)])
dnl By default, look in $includedir and $libdir.
use_additional=yes
AC_LIB_WITH_FINAL_PREFIX([
eval additional_includedir=\"$includedir\"
eval additional_libdir=\"$libdir\"
])
AC_ARG_WITH(P_A_C_K[-prefix],
[[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib
--without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]],
[
if test "X$withval" = "Xno"; then
use_additional=no
else
if test "X$withval" = "X"; then
AC_LIB_WITH_FINAL_PREFIX([
eval additional_includedir=\"$includedir\"
eval additional_libdir=\"$libdir\"
])
else
additional_includedir="$withval/include"
additional_libdir="$withval/$acl_libdirstem"
if test "$acl_libdirstem2" != "$acl_libdirstem" \
&& ! test -d "$withval/$acl_libdirstem"; then
additional_libdir="$withval/$acl_libdirstem2"
fi
fi
fi
])
dnl Search the library and its dependencies in $additional_libdir and
dnl $LDFLAGS. Using breadth-first-seach.
LIB[]NAME=
LTLIB[]NAME=
INC[]NAME=
LIB[]NAME[]_PREFIX=
dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been
dnl computed. So it has to be reset here.
HAVE_LIB[]NAME=
rpathdirs=
ltrpathdirs=
names_already_handled=
names_next_round='$1 $2'
while test -n "$names_next_round"; do
names_this_round="$names_next_round"
names_next_round=
for name in $names_this_round; do
already_handled=
for n in $names_already_handled; do
if test "$n" = "$name"; then
already_handled=yes
break
fi
done
if test -z "$already_handled"; then
names_already_handled="$names_already_handled $name"
dnl See if it was already located by an earlier AC_LIB_LINKFLAGS
dnl or AC_LIB_HAVE_LINKFLAGS call.
uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'`
eval value=\"\$HAVE_LIB$uppername\"
if test -n "$value"; then
if test "$value" = yes; then
eval value=\"\$LIB$uppername\"
test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value"
eval value=\"\$LTLIB$uppername\"
test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value"
else
dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined
dnl that this library doesn't exist. So just drop it.
:
fi
else
dnl Search the library lib$name in $additional_libdir and $LDFLAGS
dnl and the already constructed $LIBNAME/$LTLIBNAME.
found_dir=
found_la=
found_so=
found_a=
eval libname=\"$acl_libname_spec\" # typically: libname=lib$name
if test -n "$acl_shlibext"; then
shrext=".$acl_shlibext" # typically: shrext=.so
else
shrext=
fi
if test $use_additional = yes; then
dir="$additional_libdir"
dnl The same code as in the loop below:
dnl First look for a shared library.
if test -n "$acl_shlibext"; then
if test -f "$dir/$libname$shrext"; then
found_dir="$dir"
found_so="$dir/$libname$shrext"
else
if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
ver=`(cd "$dir" && \
for f in "$libname$shrext".*; do echo "$f"; done \
| sed -e "s,^$libname$shrext\\\\.,," \
| sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
| sed 1q ) 2>/dev/null`
if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
found_dir="$dir"
found_so="$dir/$libname$shrext.$ver"
fi
else
eval library_names=\"$acl_library_names_spec\"
for f in $library_names; do
if test -f "$dir/$f"; then
found_dir="$dir"
found_so="$dir/$f"
break
fi
done
fi
fi
fi
dnl Then look for a static library.
if test "X$found_dir" = "X"; then
if test -f "$dir/$libname.$acl_libext"; then
found_dir="$dir"
found_a="$dir/$libname.$acl_libext"
fi
fi
if test "X$found_dir" != "X"; then
if test -f "$dir/$libname.la"; then
found_la="$dir/$libname.la"
fi
fi
fi
if test "X$found_dir" = "X"; then
for x in $LDFLAGS $LTLIB[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
case "$x" in
-L*)
dir=`echo "X$x" | sed -e 's/^X-L//'`
dnl First look for a shared library.
if test -n "$acl_shlibext"; then
if test -f "$dir/$libname$shrext"; then
found_dir="$dir"
found_so="$dir/$libname$shrext"
else
if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
ver=`(cd "$dir" && \
for f in "$libname$shrext".*; do echo "$f"; done \
| sed -e "s,^$libname$shrext\\\\.,," \
| sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
| sed 1q ) 2>/dev/null`
if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
found_dir="$dir"
found_so="$dir/$libname$shrext.$ver"
fi
else
eval library_names=\"$acl_library_names_spec\"
for f in $library_names; do
if test -f "$dir/$f"; then
found_dir="$dir"
found_so="$dir/$f"
break
fi
done
fi
fi
fi
dnl Then look for a static library.
if test "X$found_dir" = "X"; then
if test -f "$dir/$libname.$acl_libext"; then
found_dir="$dir"
found_a="$dir/$libname.$acl_libext"
fi
fi
if test "X$found_dir" != "X"; then
if test -f "$dir/$libname.la"; then
found_la="$dir/$libname.la"
fi
fi
;;
esac
if test "X$found_dir" != "X"; then
break
fi
done
fi
if test "X$found_dir" != "X"; then
dnl Found the library.
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name"
if test "X$found_so" != "X"; then
dnl Linking with a shared library. We attempt to hardcode its
dnl directory into the executable's runpath, unless it's the
dnl standard /usr/lib.
if test "$enable_rpath" = no \
|| test "X$found_dir" = "X/usr/$acl_libdirstem" \
|| test "X$found_dir" = "X/usr/$acl_libdirstem2"; then
dnl No hardcoding is needed.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
else
dnl Use an explicit option to hardcode DIR into the resulting
dnl binary.
dnl Potentially add DIR to ltrpathdirs.
dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
haveit=
for x in $ltrpathdirs; do
if test "X$x" = "X$found_dir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
ltrpathdirs="$ltrpathdirs $found_dir"
fi
dnl The hardcoding into $LIBNAME is system dependent.
if test "$acl_hardcode_direct" = yes; then
dnl Using DIR/libNAME.so during linking hardcodes DIR into the
dnl resulting binary.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
else
if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
dnl Use an explicit option to hardcode DIR into the resulting
dnl binary.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
dnl Potentially add DIR to rpathdirs.
dnl The rpathdirs will be appended to $LIBNAME at the end.
haveit=
for x in $rpathdirs; do
if test "X$x" = "X$found_dir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
rpathdirs="$rpathdirs $found_dir"
fi
else
dnl Rely on "-L$found_dir".
dnl But don't add it if it's already contained in the LDFLAGS
dnl or the already constructed $LIBNAME
haveit=
for x in $LDFLAGS $LIB[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-L$found_dir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir"
fi
if test "$acl_hardcode_minus_L" != no; then
dnl FIXME: Not sure whether we should use
dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
dnl here.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
else
dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH
dnl here, because this doesn't fit in flags passed to the
dnl compiler. So give up. No hardcoding. This affects only
dnl very old systems.
dnl FIXME: Not sure whether we should use
dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
dnl here.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
fi
fi
fi
fi
else
if test "X$found_a" != "X"; then
dnl Linking with a static library.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a"
else
dnl We shouldn't come here, but anyway it's good to have a
dnl fallback.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name"
fi
fi
dnl Assume the include files are nearby.
additional_includedir=
case "$found_dir" in
*/$acl_libdirstem | */$acl_libdirstem/)
basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'`
if test "$name" = '$1'; then
LIB[]NAME[]_PREFIX="$basedir"
fi
additional_includedir="$basedir/include"
;;
*/$acl_libdirstem2 | */$acl_libdirstem2/)
basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'`
if test "$name" = '$1'; then
LIB[]NAME[]_PREFIX="$basedir"
fi
additional_includedir="$basedir/include"
;;
esac
if test "X$additional_includedir" != "X"; then
dnl Potentially add $additional_includedir to $INCNAME.
dnl But don't add it
dnl 1. if it's the standard /usr/include,
dnl 2. if it's /usr/local/include and we are using GCC on Linux,
dnl 3. if it's already present in $CPPFLAGS or the already
dnl constructed $INCNAME,
dnl 4. if it doesn't exist as a directory.
if test "X$additional_includedir" != "X/usr/include"; then
haveit=
if test "X$additional_includedir" = "X/usr/local/include"; then
if test -n "$GCC"; then
case $host_os in
linux* | gnu* | k*bsd*-gnu) haveit=yes;;
esac
fi
fi
if test -z "$haveit"; then
for x in $CPPFLAGS $INC[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-I$additional_includedir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
if test -d "$additional_includedir"; then
dnl Really add $additional_includedir to $INCNAME.
INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir"
fi
fi
fi
fi
fi
dnl Look for dependencies.
if test -n "$found_la"; then
dnl Read the .la file. It defines the variables
dnl dlname, library_names, old_library, dependency_libs, current,
dnl age, revision, installed, dlopen, dlpreopen, libdir.
save_libdir="$libdir"
case "$found_la" in
*/* | *\\*) . "$found_la" ;;
*) . "./$found_la" ;;
esac
libdir="$save_libdir"
dnl We use only dependency_libs.
for dep in $dependency_libs; do
case "$dep" in
-L*)
additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.
dnl But don't add it
dnl 1. if it's the standard /usr/lib,
dnl 2. if it's /usr/local/lib and we are using GCC on Linux,
dnl 3. if it's already present in $LDFLAGS or the already
dnl constructed $LIBNAME,
dnl 4. if it doesn't exist as a directory.
if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \
&& test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then
haveit=
if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \
|| test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then
if test -n "$GCC"; then
case $host_os in
linux* | gnu* | k*bsd*-gnu) haveit=yes;;
esac
fi
fi
if test -z "$haveit"; then
haveit=
for x in $LDFLAGS $LIB[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-L$additional_libdir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
if test -d "$additional_libdir"; then
dnl Really add $additional_libdir to $LIBNAME.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir"
fi
fi
haveit=
for x in $LDFLAGS $LTLIB[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-L$additional_libdir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
if test -d "$additional_libdir"; then
dnl Really add $additional_libdir to $LTLIBNAME.
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir"
fi
fi
fi
fi
;;
-R*)
dir=`echo "X$dep" | sed -e 's/^X-R//'`
if test "$enable_rpath" != no; then
dnl Potentially add DIR to rpathdirs.
dnl The rpathdirs will be appended to $LIBNAME at the end.
haveit=
for x in $rpathdirs; do
if test "X$x" = "X$dir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
rpathdirs="$rpathdirs $dir"
fi
dnl Potentially add DIR to ltrpathdirs.
dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
haveit=
for x in $ltrpathdirs; do
if test "X$x" = "X$dir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
ltrpathdirs="$ltrpathdirs $dir"
fi
fi
;;
-l*)
dnl Handle this in the next round.
names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
;;
*.la)
dnl Handle this in the next round. Throw away the .la's
dnl directory; it is already contained in a preceding -L
dnl option.
names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
;;
*)
dnl Most likely an immediate library name.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep"
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep"
;;
esac
done
fi
else
dnl Didn't find the library; assume it is in the system directories
dnl known to the linker and runtime loader. (All the system
dnl directories known to the linker should also be known to the
dnl runtime loader, otherwise the system is severely misconfigured.)
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name"
fi
fi
fi
done
done
if test "X$rpathdirs" != "X"; then
if test -n "$acl_hardcode_libdir_separator"; then
dnl Weird platform: only the last -rpath option counts, the user must
dnl pass all path elements in one option. We can arrange that for a
dnl single library, but not when more than one $LIBNAMEs are used.
alldirs=
for found_dir in $rpathdirs; do
alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir"
done
dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl.
acl_save_libdir="$libdir"
libdir="$alldirs"
eval flag=\"$acl_hardcode_libdir_flag_spec\"
libdir="$acl_save_libdir"
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
else
dnl The -rpath options are cumulative.
for found_dir in $rpathdirs; do
acl_save_libdir="$libdir"
libdir="$found_dir"
eval flag=\"$acl_hardcode_libdir_flag_spec\"
libdir="$acl_save_libdir"
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
done
fi
fi
if test "X$ltrpathdirs" != "X"; then
dnl When using libtool, the option that works for both libraries and
dnl executables is -R. The -R options are cumulative.
for found_dir in $ltrpathdirs; do
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
done
fi
popdef([P_A_C_K])
popdef([PACKLIBS])
popdef([PACKUP])
popdef([PACK])
popdef([NAME])
])
dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR,
dnl unless already present in VAR.
dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes
dnl contains two or three consecutive elements that belong together.
AC_DEFUN([AC_LIB_APPENDTOVAR],
[
for element in [$2]; do
haveit=
for x in $[$1]; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X$element"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
[$1]="${[$1]}${[$1]:+ }$element"
fi
done
])
dnl For those cases where a variable contains several -L and -l options
dnl referring to unknown libraries and directories, this macro determines the
dnl necessary additional linker options for the runtime path.
dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL])
dnl sets LDADDVAR to linker options needed together with LIBSVALUE.
dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed,
dnl otherwise linking without libtool is assumed.
AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],
[
AC_REQUIRE([AC_LIB_RPATH])
AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
$1=
if test "$enable_rpath" != no; then
if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
dnl Use an explicit option to hardcode directories into the resulting
dnl binary.
rpathdirs=
next=
for opt in $2; do
if test -n "$next"; then
dir="$next"
dnl No need to hardcode the standard /usr/lib.
if test "X$dir" != "X/usr/$acl_libdirstem" \
&& test "X$dir" != "X/usr/$acl_libdirstem2"; then
rpathdirs="$rpathdirs $dir"
fi
next=
else
case $opt in
-L) next=yes ;;
-L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'`
dnl No need to hardcode the standard /usr/lib.
if test "X$dir" != "X/usr/$acl_libdirstem" \
&& test "X$dir" != "X/usr/$acl_libdirstem2"; then
rpathdirs="$rpathdirs $dir"
fi
next= ;;
*) next= ;;
esac
fi
done
if test "X$rpathdirs" != "X"; then
if test -n ""$3""; then
dnl libtool is used for linking. Use -R options.
for dir in $rpathdirs; do
$1="${$1}${$1:+ }-R$dir"
done
else
dnl The linker is used for linking directly.
if test -n "$acl_hardcode_libdir_separator"; then
dnl Weird platform: only the last -rpath option counts, the user
dnl must pass all path elements in one option.
alldirs=
for dir in $rpathdirs; do
alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir"
done
acl_save_libdir="$libdir"
libdir="$alldirs"
eval flag=\"$acl_hardcode_libdir_flag_spec\"
libdir="$acl_save_libdir"
$1="$flag"
else
dnl The -rpath options are cumulative.
for dir in $rpathdirs; do
acl_save_libdir="$libdir"
libdir="$dir"
eval flag=\"$acl_hardcode_libdir_flag_spec\"
libdir="$acl_save_libdir"
$1="${$1}${$1:+ }$flag"
done
fi
fi
fi
fi
fi
AC_SUBST([$1])
])

View file

@ -0,0 +1,224 @@
# lib-prefix.m4 serial 7 (gettext-0.18)
dnl Copyright (C) 2001-2005, 2008-2011 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Bruno Haible.
dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and
dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't
dnl require excessive bracketing.
ifdef([AC_HELP_STRING],
[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])],
[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])])
dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed
dnl to access previously installed libraries. The basic assumption is that
dnl a user will want packages to use other packages he previously installed
dnl with the same --prefix option.
dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate
dnl libraries, but is otherwise very convenient.
AC_DEFUN([AC_LIB_PREFIX],
[
AC_BEFORE([$0], [AC_LIB_LINKFLAGS])
AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([AC_CANONICAL_HOST])
AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
dnl By default, look in $includedir and $libdir.
use_additional=yes
AC_LIB_WITH_FINAL_PREFIX([
eval additional_includedir=\"$includedir\"
eval additional_libdir=\"$libdir\"
])
AC_LIB_ARG_WITH([lib-prefix],
[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
--without-lib-prefix don't search for libraries in includedir and libdir],
[
if test "X$withval" = "Xno"; then
use_additional=no
else
if test "X$withval" = "X"; then
AC_LIB_WITH_FINAL_PREFIX([
eval additional_includedir=\"$includedir\"
eval additional_libdir=\"$libdir\"
])
else
additional_includedir="$withval/include"
additional_libdir="$withval/$acl_libdirstem"
fi
fi
])
if test $use_additional = yes; then
dnl Potentially add $additional_includedir to $CPPFLAGS.
dnl But don't add it
dnl 1. if it's the standard /usr/include,
dnl 2. if it's already present in $CPPFLAGS,
dnl 3. if it's /usr/local/include and we are using GCC on Linux,
dnl 4. if it doesn't exist as a directory.
if test "X$additional_includedir" != "X/usr/include"; then
haveit=
for x in $CPPFLAGS; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-I$additional_includedir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
if test "X$additional_includedir" = "X/usr/local/include"; then
if test -n "$GCC"; then
case $host_os in
linux* | gnu* | k*bsd*-gnu) haveit=yes;;
esac
fi
fi
if test -z "$haveit"; then
if test -d "$additional_includedir"; then
dnl Really add $additional_includedir to $CPPFLAGS.
CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir"
fi
fi
fi
fi
dnl Potentially add $additional_libdir to $LDFLAGS.
dnl But don't add it
dnl 1. if it's the standard /usr/lib,
dnl 2. if it's already present in $LDFLAGS,
dnl 3. if it's /usr/local/lib and we are using GCC on Linux,
dnl 4. if it doesn't exist as a directory.
if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then
haveit=
for x in $LDFLAGS; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-L$additional_libdir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then
if test -n "$GCC"; then
case $host_os in
linux*) haveit=yes;;
esac
fi
fi
if test -z "$haveit"; then
if test -d "$additional_libdir"; then
dnl Really add $additional_libdir to $LDFLAGS.
LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir"
fi
fi
fi
fi
fi
])
dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix,
dnl acl_final_exec_prefix, containing the values to which $prefix and
dnl $exec_prefix will expand at the end of the configure script.
AC_DEFUN([AC_LIB_PREPARE_PREFIX],
[
dnl Unfortunately, prefix and exec_prefix get only finally determined
dnl at the end of configure.
if test "X$prefix" = "XNONE"; then
acl_final_prefix="$ac_default_prefix"
else
acl_final_prefix="$prefix"
fi
if test "X$exec_prefix" = "XNONE"; then
acl_final_exec_prefix='${prefix}'
else
acl_final_exec_prefix="$exec_prefix"
fi
acl_save_prefix="$prefix"
prefix="$acl_final_prefix"
eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
prefix="$acl_save_prefix"
])
dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the
dnl variables prefix and exec_prefix bound to the values they will have
dnl at the end of the configure script.
AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],
[
acl_save_prefix="$prefix"
prefix="$acl_final_prefix"
acl_save_exec_prefix="$exec_prefix"
exec_prefix="$acl_final_exec_prefix"
$1
exec_prefix="$acl_save_exec_prefix"
prefix="$acl_save_prefix"
])
dnl AC_LIB_PREPARE_MULTILIB creates
dnl - a variable acl_libdirstem, containing the basename of the libdir, either
dnl "lib" or "lib64" or "lib/64",
dnl - a variable acl_libdirstem2, as a secondary possible value for
dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or
dnl "lib/amd64".
AC_DEFUN([AC_LIB_PREPARE_MULTILIB],
[
dnl There is no formal standard regarding lib and lib64.
dnl On glibc systems, the current practice is that on a system supporting
dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine
dnl the compiler's default mode by looking at the compiler's library search
dnl path. If at least one of its elements ends in /lib64 or points to a
dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI.
dnl Otherwise we use the default, namely "lib".
dnl On Solaris systems, the current practice is that on a system supporting
dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or
dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib.
AC_REQUIRE([AC_CANONICAL_HOST])
acl_libdirstem=lib
acl_libdirstem2=
case "$host_os" in
solaris*)
dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment
dnl <http://docs.sun.com/app/docs/doc/816-5138/dev-env?l=en&a=view>.
dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link."
dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the
dnl symlink is missing, so we set acl_libdirstem2 too.
AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit],
[AC_EGREP_CPP([sixtyfour bits], [
#ifdef _LP64
sixtyfour bits
#endif
], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no])
])
if test $gl_cv_solaris_64bit = yes; then
acl_libdirstem=lib/64
case "$host_cpu" in
sparc*) acl_libdirstem2=lib/sparcv9 ;;
i*86 | x86_64) acl_libdirstem2=lib/amd64 ;;
esac
fi
;;
*)
searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
if test -n "$searchpath"; then
acl_save_IFS="${IFS= }"; IFS=":"
for searchdir in $searchpath; do
if test -d "$searchdir"; then
case "$searchdir" in
*/lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
*/../ | */.. )
# Better ignore directories of this form. They are misleading.
;;
*) searchdir=`cd "$searchdir" && pwd`
case "$searchdir" in
*/lib64 ) acl_libdirstem=lib64 ;;
esac ;;
esac
fi
done
IFS="$acl_save_IFS"
fi
;;
esac
test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
])

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,331 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2012-01-06.13; # UTC
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program 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 General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
msg="missing on your system"
case $1 in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
autom4te touch the output file, or create a stub one
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
\`g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
esac
# normalize program name to check for.
program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`
# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program). This is about non-GNU programs, so use $1 not
# $program.
case $1 in
lex*|yacc*)
# Not GNU programs, they don't have --version.
;;
*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
# Could not run --version or --help. This is probably someone
# running `$TOOL --version' or `$TOOL --help' to check whether
# $TOOL exists and not knowing $TOOL uses missing.
exit 1
fi
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case $program in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case $f in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te*)
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison*|yacc*)
echo 1>&2 "\
WARNING: \`$1' $msg. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if test $# -ne 1; then
eval LASTARG=\${$#}
case $LASTARG in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if test ! -f y.tab.h; then
echo >y.tab.h
fi
if test ! -f y.tab.c; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex*|flex*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if test $# -ne 1; then
eval LASTARG=\${$#}
case $LASTARG in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if test ! -f lex.yy.c; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit $?
fi
;;
makeinfo*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '
/^@setfilename/{
s/.* \([^ ]*\) *$/\1/
p
q
}' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
# If the file does not exist, the user really needs makeinfo;
# let's fail without touching anything.
test -f $file || exit 1
touch $file
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

View file

@ -0,0 +1,67 @@
#!/bin/sh
PATH=/usr/local/gnu-autotools/bin/:$PATH
export PATH
# Start from one level above the build directory
if [ -f version ]; then
cd ..
fi
if [ \! -f build/version ]; then
echo "Can't find source directory"
exit 1
fi
# BSD make's "OBJDIR" support freaks out the automake-generated
# Makefile. Effectively disable it.
export MAKEOBJDIRPREFIX=/junk
# Start from the build directory, where the version file is located
if [ -f build/version ]; then
cd build
fi
if [ \! -f version ]; then
echo "Can't find version file"
exit 1
fi
# Update the build number in the 'version' file.
# Separate number from additional alpha/beta/etc marker
MARKER=`cat version | sed 's/[0-9.]//g'`
# Bump the number
VN=`cat version | sed 's/[^0-9.]//g'`
# Build out the string.
VS="$(($VN/1000000)).$(( ($VN/1000)%1000 )).$(( $VN%1000 ))$MARKER"
cd ..
# Clean up the source dir as much as we can.
/bin/sh build/clean.sh
# Substitute the versions into Libarchive's archive.h and archive_entry.h
perl -p -i -e "s/^(#define\tARCHIVE_VERSION_NUMBER).*/\$1 $VN/" libarchive/archive.h
perl -p -i -e "s/^(#define\tARCHIVE_VERSION_NUMBER).*/\$1 $VN/" libarchive/archive_entry.h
perl -p -i -e "s/^(#define\tARCHIVE_VERSION_STRING).*/\$1 \"libarchive $VS\"/" libarchive/archive.h
# Substitute versions into configure.ac as well
perl -p -i -e 's/(m4_define\(\[LIBARCHIVE_VERSION_S\]),.*\)/$1,['"$VS"'])/' configure.ac
perl -p -i -e 's/(m4_define\(\[LIBARCHIVE_VERSION_N\]),.*\)/$1,['"$VN"'])/' configure.ac
# Remove developer CFLAGS if a release build is being made
if [ -n "${MAKE_LIBARCHIVE_RELEASE}" ]; then
perl -p -i -e "s/^(DEV_CFLAGS.*)/# \$1/" Makefile.am
fi
set -xe
aclocal -I build/autoconf
# Note: --automake flag needed only for libtoolize from
# libtool 1.5.x; in libtool 2.2.x it is a synonym for --quiet
case `uname` in
Darwin) glibtoolize --automake -c;;
*) libtoolize --automake -c;;
esac
autoconf
autoheader
automake -a -c

View file

@ -0,0 +1,36 @@
#!/bin/sh +v
# Start from the build directory, where the version file is located
if [ -f build/version ]; then
cd build
fi
if [ \! -f version ]; then
echo "Can't find version file"
exit 1
fi
# Update the build number in the 'version' file.
# Separate number from additional alpha/beta/etc marker
MARKER=`cat version | sed 's/[0-9.]//g'`
# Bump the number
VN=`cat version | sed 's/[^0-9.]//g'`
# Reassemble and write back out
VN=$(($VN + 1))
rm -f version.old
mv version version.old
chmod +w version.old
echo $VN$MARKER > version
VS="$(($VN/1000000)).$(( ($VN/1000)%1000 )).$(( $VN%1000 ))$MARKER"
cd ..
ANNOUNCE=`date +"%b %d, %Y:"`" libarchive $VS released"
echo $ANNOUNCE
# Add a version notice to NEWS
mv NEWS NEWS.bak
chmod +w NEWS.bak
echo $ANNOUNCE >> NEWS
echo >> NEWS
cat NEWS.bak >> NEWS

View file

@ -0,0 +1,97 @@
#!/bin/sh
#
# Attempt to remove as many generated files as we can.
# Ideally, a well-used development sandbox would look like
# a pristine checkout after running this script.
#
if [ \! -f build/version ]; then
echo 'Must run the clean script from the top-level dir of the libarchive distribution' 1>&2
exit 1
fi
# If we're on BSD, blow away the build dir under /usr/obj
rm -rf /usr/obj`pwd`
#
# Try to clean up a bit more...
#
find . -name '*.So' | xargs rm -f
find . -name '*.a' | xargs rm -f
find . -name '*.la' | xargs rm -f
find . -name '*.lo' | xargs rm -f
find . -name '*.o' | xargs rm -f
find . -name '*.orig' | xargs rm -f
find . -name '*.po' | xargs rm -f
find . -name '*.rej' | xargs rm -f
find . -name '*~' | xargs rm -f
find . -name '.depend' | xargs rm -f
find . -name '.deps' | xargs rm -rf
find . -name '.dirstamp' | xargs rm -f
find . -name '.libs' | xargs rm -rf
find . -name 'CMakeFiles' | xargs rm -rf
find . -name 'cmake_install.cmake' | xargs rm -f
find . -name 'CTestTestfile.cmake' | xargs rm -f
rm -rf Testing
rm -rf autom4te.cache
rm -rf bin
rm -rf cmake.tmp
rm -rf libarchive/Testing
rm -f CMakeCache.txt
rm -f DartConfiguration.tcl
rm -f Makefile
rm -f Makefile.in
rm -f aclocal.m4
rm -f bsdcpio
rm -f bsdcpio_test
rm -f bsdtar
rm -f bsdtar_test
rm -f build/autoconf/compile
rm -f build/autoconf/config.guess
rm -f build/autoconf/config.sub
rm -f build/autoconf/depcomp
rm -f build/autoconf/install-sh
rm -f build/autoconf/libtool.m4
rm -f build/autoconf/ltmain.sh
rm -f build/autoconf/ltoptions.m4
rm -f build/autoconf/ltsugar.m4
rm -f build/autoconf/ltversion.m4
rm -f build/autoconf/lt~obsolete.m4
rm -f build/autoconf/missing
rm -f build/pkgconfig/libarchive.pc
rm -f build/version.old
rm -f config.h
rm -f config.h.in
rm -f config.log
rm -f config.status
rm -f configure
rm -f cpio/*.1.gz
rm -f cpio/Makefile
rm -f cpio/bsdcpio
rm -f cpio/test/Makefile
rm -f cpio/test/bsdcpio_test
rm -f cpio/test/list.h
rm -f doc/html/*
rm -f doc/man/*
rm -f doc/pdf/*
rm -f doc/text/*
rm -f doc/wiki/*
rm -f libarchive/*.[35].gz
rm -f libarchive/Makefile
rm -f libarchive/libarchive.so*
rm -f libarchive/test/Makefile
rm -f libarchive/test/libarchive_test
rm -f libarchive/test/list.h
rm -f libarchive_test
rm -f libtool
rm -f stamp-h1
rm -f tar/*.1.gz
rm -f tar/Makefile
rm -f tar/bsdtar
rm -f tar/test/Makefile
rm -f tar/test/bsdtar_test
rm -f tar/test/list.h

View file

@ -0,0 +1,14 @@
#include <sys/types.h>
#define KB ((off_t)1024)
#define MB ((off_t)1024 * KB)
#define GB ((off_t)1024 * MB)
#define TB ((off_t)1024 * GB)
int t2[(((64 * GB -1) % 671088649) == 268434537)
&& (((TB - (64 * GB -1) + 255) % 1792151290) == 305159546)? 1: -1];
int main()
{
;
return 0;
}

View file

@ -0,0 +1,44 @@
# - Check if _FILE_OFFSET_BITS macro needed for large files
# CHECK_FILE_OFFSET_BITS ()
#
# The following variables may be set before calling this macro to
# modify the way the check is run:
#
# CMAKE_REQUIRED_FLAGS = string of compile command line flags
# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
# CMAKE_REQUIRED_INCLUDES = list of include directories
# Copyright (c) 2009, Michihiro NAKAJIMA
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#INCLUDE(CheckCXXSourceCompiles)
GET_FILENAME_COMPONENT(_selfdir_CheckFileOffsetBits
"${CMAKE_CURRENT_LIST_FILE}" PATH)
MACRO (CHECK_FILE_OFFSET_BITS)
IF(NOT DEFINED _FILE_OFFSET_BITS)
MESSAGE(STATUS "Checking _FILE_OFFSET_BITS for large files")
TRY_COMPILE(__WITHOUT_FILE_OFFSET_BITS_64
${CMAKE_CURRENT_BINARY_DIR}
${_selfdir_CheckFileOffsetBits}/CheckFileOffsetBits.c
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS})
IF(NOT __WITHOUT_FILE_OFFSET_BITS_64)
TRY_COMPILE(__WITH_FILE_OFFSET_BITS_64
${CMAKE_CURRENT_BINARY_DIR}
${_selfdir_CheckFileOffsetBits}/CheckFileOffsetBits.c
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -D_FILE_OFFSET_BITS=64)
ENDIF(NOT __WITHOUT_FILE_OFFSET_BITS_64)
IF(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64)
SET(_FILE_OFFSET_BITS 64 CACHE INTERNAL "_FILE_OFFSET_BITS macro needed for large files")
MESSAGE(STATUS "Checking _FILE_OFFSET_BITS for large files - needed")
ELSE(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64)
SET(_FILE_OFFSET_BITS "" CACHE INTERNAL "_FILE_OFFSET_BITS macro needed for large files")
MESSAGE(STATUS "Checking _FILE_OFFSET_BITS for large files - not needed")
ENDIF(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64)
ENDIF(NOT DEFINED _FILE_OFFSET_BITS)
ENDMACRO (CHECK_FILE_OFFSET_BITS)

View file

@ -0,0 +1,49 @@
# Check if the system has the specified function; treat glibc "stub"
# functions as nonexistent:
# CHECK_FUNCTION_EXISTS_GLIBC (FUNCTION FUNCVAR)
#
# FUNCTION - the function(s) where the prototype should be declared
# FUNCVAR - variable to define if the function does exist
#
# In particular, this understands the glibc convention of
# defining macros __stub_XXXX or __stub___XXXX if the function
# does appear in the library but is merely a stub that does nothing.
# By detecting this case, we can select alternate behavior on
# platforms that don't support this functionality.
#
# The following variables may be set before calling this macro to
# modify the way the check is run:
#
# CMAKE_REQUIRED_FLAGS = string of compile command line flags
# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
# CMAKE_REQUIRED_INCLUDES = list of include directories
# Copyright (c) 2009, Michihiro NAKAJIMA
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
INCLUDE(CheckFunctionExists)
GET_FILENAME_COMPONENT(_selfdir_CheckFunctionExistsGlibc
"${CMAKE_CURRENT_LIST_FILE}" PATH)
MACRO (CHECK_FUNCTION_EXISTS_GLIBC _FUNC _FUNCVAR)
IF(NOT DEFINED ${_FUNCVAR})
SET(CHECK_STUB_FUNC_1 "__stub_${_FUNC}")
SET(CHECK_STUB_FUNC_2 "__stub___${_FUNC}")
CONFIGURE_FILE( ${_selfdir_CheckFunctionExistsGlibc}/CheckFuncs_stub.c.in
${CMAKE_CURRENT_BINARY_DIR}/cmake.tmp/CheckFuncs_stub.c IMMEDIATE)
TRY_COMPILE(__stub
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}/cmake.tmp/CheckFuncs_stub.c
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
CMAKE_FLAGS
-DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILE_FLAGS}
"${CHECK_INCLUDE_FILE_C_INCLUDE_DIRS}")
IF (__stub)
SET("${_FUNCVAR}" "" CACHE INTERNAL "Have function ${_FUNC}")
ELSE (__stub)
CHECK_FUNCTION_EXISTS("${_FUNC}" "${_FUNCVAR}")
ENDIF (__stub)
ENDIF(NOT DEFINED ${_FUNCVAR})
ENDMACRO (CHECK_FUNCTION_EXISTS_GLIBC)

View file

@ -0,0 +1,16 @@
#ifdef __STDC__
#include <limits.h>
#else
#include <assert.h>
#endif
int
main()
{
#if defined ${CHECK_STUB_FUNC_1} || defined ${CHECK_STUB_FUNC_2}
return 0;
#else
this system have stub
return 0;
#endif
}

View file

@ -0,0 +1,32 @@
# - Check if the system has the specified type
# CHECK_HEADER_DIRENT (HEADER1 HEARDER2 ...)
#
# HEADER - the header(s) where the prototype should be declared
#
# The following variables may be set before calling this macro to
# modify the way the check is run:
#
# CMAKE_REQUIRED_FLAGS = string of compile command line flags
# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
# CMAKE_REQUIRED_INCLUDES = list of include directories
# Copyright (c) 2009, Michihiro NAKAJIMA
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
INCLUDE(CheckTypeExists)
MACRO (CHECK_HEADER_DIRENT)
CHECK_TYPE_EXISTS("DIR *" dirent.h HAVE_DIRENT_H)
IF(NOT HAVE_DIRENT_H)
CHECK_TYPE_EXISTS("DIR *" sys/ndir.h HAVE_SYS_NDIR_H)
IF(NOT HAVE_SYS_NDIR_H)
CHECK_TYPE_EXISTS("DIR *" ndir.h HAVE_NDIR_H)
IF(NOT HAVE_NDIR_H)
CHECK_TYPE_EXISTS("DIR *" sys/dir.h HAVE_SYS_DIR_H)
ENDIF(NOT HAVE_NDIR_H)
ENDIF(NOT HAVE_SYS_NDIR_H)
ENDIF(NOT HAVE_DIRENT_H)
ENDMACRO (CHECK_HEADER_DIRENT)

View file

@ -0,0 +1,43 @@
# - Check if the given struct or class has the specified member variable
# CHECK_STRUCT_MEMBER (STRUCT MEMBER HEADER VARIABLE)
#
# STRUCT - the name of the struct or class you are interested in
# MEMBER - the member which existence you want to check
# HEADER - the header(s) where the prototype should be declared
# VARIABLE - variable to store the result
#
# The following variables may be set before calling this macro to
# modify the way the check is run:
#
# CMAKE_REQUIRED_FLAGS = string of compile command line flags
# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
# CMAKE_REQUIRED_INCLUDES = list of include directories
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
INCLUDE(CheckCSourceCompiles)
MACRO (CHECK_STRUCT_MEMBER _STRUCT _MEMBER _HEADER _RESULT)
SET(_INCLUDE_FILES)
FOREACH (it ${_HEADER})
SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n")
ENDFOREACH (it)
SET(_CHECK_STRUCT_MEMBER_SOURCE_CODE "
${_INCLUDE_FILES}
int main()
{
static ${_STRUCT} tmp;
if (sizeof(tmp.${_MEMBER}))
return 0;
return 0;
}
")
CHECK_C_SOURCE_COMPILES("${_CHECK_STRUCT_MEMBER_SOURCE_CODE}" ${_RESULT})
ENDMACRO (CHECK_STRUCT_MEMBER)

View file

@ -0,0 +1,42 @@
# - Check if the system has the specified type
# CHECK_TYPE_EXISTS (TYPE HEADER VARIABLE)
#
# TYPE - the name of the type or struct or class you are interested in
# HEADER - the header(s) where the prototype should be declared
# VARIABLE - variable to store the result
#
# The following variables may be set before calling this macro to
# modify the way the check is run:
#
# CMAKE_REQUIRED_FLAGS = string of compile command line flags
# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
# CMAKE_REQUIRED_INCLUDES = list of include directories
# Copyright (c) 2009, Michihiro NAKAJIMA
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
INCLUDE(CheckCSourceCompiles)
MACRO (CHECK_TYPE_EXISTS _TYPE _HEADER _RESULT)
SET(_INCLUDE_FILES)
FOREACH (it ${_HEADER})
SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n")
ENDFOREACH (it)
SET(_CHECK_TYPE_EXISTS_SOURCE_CODE "
${_INCLUDE_FILES}
int main()
{
static ${_TYPE} tmp;
if (sizeof(tmp))
return 0;
return 0;
}
")
CHECK_C_SOURCE_COMPILES("${_CHECK_TYPE_EXISTS_SOURCE_CODE}" ${_RESULT})
ENDMACRO (CHECK_TYPE_EXISTS)

View file

@ -0,0 +1,48 @@
# - Find lzma and lzmadec
# Find the native LZMA includes and library
#
# LZMA_INCLUDE_DIR - where to find lzma.h, etc.
# LZMA_LIBRARIES - List of libraries when using liblzma.
# LZMA_FOUND - True if liblzma found.
# LZMADEC_INCLUDE_DIR - where to find lzmadec.h, etc.
# LZMADEC_LIBRARIES - List of libraries when using liblzmadec.
# LZMADEC_FOUND - True if liblzmadec found.
IF (LZMA_INCLUDE_DIR)
# Already in cache, be silent
SET(LZMA_FIND_QUIETLY TRUE)
ENDIF (LZMA_INCLUDE_DIR)
FIND_PATH(LZMA_INCLUDE_DIR lzma.h)
FIND_LIBRARY(LZMA_LIBRARY NAMES lzma liblzma)
# handle the QUIETLY and REQUIRED arguments and set LZMA_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LZMA DEFAULT_MSG LZMA_LIBRARY LZMA_INCLUDE_DIR)
IF(LZMA_FOUND)
SET( LZMA_LIBRARIES ${LZMA_LIBRARY} )
ELSE(LZMA_FOUND)
SET( LZMA_LIBRARIES )
IF (LZMADEC_INCLUDE_DIR)
# Already in cache, be silent
SET(LZMADEC_FIND_QUIETLY TRUE)
ENDIF (LZMADEC_INCLUDE_DIR)
FIND_PATH(LZMADEC_INCLUDE_DIR lzmadec.h)
FIND_LIBRARY(LZMADEC_LIBRARY NAMES lzmadec )
# handle the QUIETLY and REQUIRED arguments and set LZMADEC_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LZMADEC DEFAULT_MSG LZMADEC_LIBRARY
LZMADEC_INCLUDE_DIR)
IF(LZMADEC_FOUND)
SET( LZMADEC_LIBRARIES ${LZMADEC_LIBRARY} )
ELSE(LZMADEC_FOUND)
SET( LZMADEC_LIBRARIES )
ENDIF(LZMADEC_FOUND)
ENDIF(LZMA_FOUND)

View file

@ -0,0 +1,22 @@
# - Find libgcc
# Find the libgcc library.
#
# LIBGCC_LIBRARIES - List of libraries when using libgcc
# LIBGCC_FOUND - True if libgcc found.
IF (LIBGCC_LIBRARY)
# Already in cache, be silent
SET(LIBGCC_FIND_QUIETLY TRUE)
ENDIF (LIBGCC_LIBRARY)
FIND_LIBRARY(LIBGCC_LIBRARY NAMES gcc libgcc)
# handle the QUIETLY and REQUIRED arguments and set LIBGCC_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBGCC DEFAULT_MSG LIBGCC_LIBRARY)
IF(LIBGCC_FOUND)
SET(LIBGCC_LIBRARIES ${LIBGCC_LIBRARY})
SET(HAVE_LIBGCC 1)
ENDIF(LIBGCC_FOUND)

View file

@ -0,0 +1,23 @@
# - Find Nettle
# Find the Nettle include directory and library
#
# NETTLE_INCLUDE_DIR - where to find <nettle/sha.h>, etc.
# NETTLE_LIBRARIES - List of libraries when using libnettle.
# NETTLE_FOUND - True if libnettle found.
IF (NETTLE_INCLUDE_DIR)
# Already in cache, be silent
SET(NETTLE_FIND_QUIETLY TRUE)
ENDIF (NETTLE_INCLUDE_DIR)
FIND_PATH(NETTLE_INCLUDE_DIR nettle/md5.h nettle/ripemd160.h nettle/sha.h)
FIND_LIBRARY(NETTLE_LIBRARY NAMES nettle libnettle)
# handle the QUIETLY and REQUIRED arguments and set NETTLE_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(NETTLE DEFAULT_MSG NETTLE_LIBRARY NETTLE_INCLUDE_DIR)
IF(NETTLE_FOUND)
SET(NETTLE_LIBRARIES ${NETTLE_LIBRARY})
ENDIF(NETTLE_FOUND)

View file

@ -0,0 +1,34 @@
# - Find pcreposix
# Find the native PCRE and PCREPOSIX include and libraries
#
# PCRE_INCLUDE_DIR - where to find pcreposix.h, etc.
# PCREPOSIX_LIBRARIES - List of libraries when using libpcreposix.
# PCRE_LIBRARIES - List of libraries when using libpcre.
# PCREPOSIX_FOUND - True if libpcreposix found.
# PCRE_FOUND - True if libpcre found.
IF (PCRE_INCLUDE_DIR)
# Already in cache, be silent
SET(PCRE_FIND_QUIETLY TRUE)
ENDIF (PCRE_INCLUDE_DIR)
FIND_PATH(PCRE_INCLUDE_DIR pcreposix.h)
FIND_LIBRARY(PCREPOSIX_LIBRARY NAMES pcreposix libpcreposix)
FIND_LIBRARY(PCRE_LIBRARY NAMES pcre libpcre)
# handle the QUIETLY and REQUIRED arguments and set PCREPOSIX_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCREPOSIX DEFAULT_MSG PCREPOSIX_LIBRARY PCRE_INCLUDE_DIR)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE DEFAULT_MSG PCRE_LIBRARY)
IF(PCREPOSIX_FOUND)
SET(PCREPOSIX_LIBRARIES ${PCREPOSIX_LIBRARY})
SET(HAVE_LIBPCREPOSIX 1)
SET(HAVE_PCREPOSIX_H 1)
ENDIF(PCREPOSIX_FOUND)
IF(PCRE_FOUND)
SET(PCRE_LIBRARIES ${PCRE_LIBRARY})
SET(HAVE_LIBPCRE 1)
ENDIF(PCRE_FOUND)

View file

@ -0,0 +1,106 @@
# - Check if given C source compiles and links into an executable
# CHECK_C_SOURCE_COMPILES(<code> <var> [FAIL_REGEX <fail-regex>])
# <code> - source code to try to compile, must define 'main'
# <var> - variable to store whether the source code compiled
# <fail-regex> - fail if test output matches this regex
# The following variables may be set before calling this macro to
# modify the way the check is run:
#
# CMAKE_REQUIRED_FLAGS = string of compile command line flags
# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
# CMAKE_REQUIRED_INCLUDES = list of include directories
# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
#=============================================================================
# Copyright 2005-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
#
# Extra arguments added by libarchive
# CMAKE_REQUIRED_LINKER_FLAGS = string of linker command line flags
#
include(CMakeExpandImportedTargets)
macro(LIBARCHIVE_CHECK_C_SOURCE_COMPILES SOURCE VAR)
if("${VAR}" MATCHES "^${VAR}$")
set(_FAIL_REGEX)
set(_key)
foreach(arg ${ARGN})
if("${arg}" MATCHES "^(FAIL_REGEX)$")
set(_key "${arg}")
elseif(_key)
list(APPEND _${_key} "${arg}")
else()
message(FATAL_ERROR "Unknown argument:\n ${arg}\n")
endif()
endforeach()
set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
if(CMAKE_REQUIRED_LIBRARIES)
# this one translates potentially used imported library targets to their files on disk
CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
"-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
else()
set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
endif()
if(CMAKE_REQUIRED_INCLUDES)
set(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
else()
set(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
endif()
if(CMAKE_REQUIRED_LINKER_FLAGS)
set(CHECK_C_SOURCE_COMPILES_ADD_LINKER_FLAGS
"-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS}")
else()
set(CHECK_C_SOURCE_COMPILES_ADD_LINKER_FLAGS)
endif()
file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c"
"${SOURCE}\n")
message(STATUS "Performing Test ${VAR}")
try_compile(${VAR}
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} ${CHECK_C_SOURCE_COMPILES_ADD_LINKER_FLAGS}
"${CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}"
"${CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}"
OUTPUT_VARIABLE OUTPUT)
foreach(_regex ${_FAIL_REGEX})
if("${OUTPUT}" MATCHES "${_regex}")
set(${VAR} 0)
endif()
endforeach()
if(${VAR})
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
message(STATUS "Performing Test ${VAR} - Success")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n"
"${OUTPUT}\n"
"Source file was:\n${SOURCE}\n")
else()
message(STATUS "Performing Test ${VAR} - Failed")
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing C SOURCE FILE Test ${VAR} failed with the following output:\n"
"${OUTPUT}\n"
"Source file was:\n${SOURCE}\n")
endif()
endif()
endmacro()

View file

@ -0,0 +1,102 @@
# - Check if the given C source code compiles and runs.
# CHECK_C_SOURCE_RUNS(<code> <var>)
# <code> - source code to try to compile
# <var> - variable to store the result
# (1 for success, empty for failure)
# The following variables may be set before calling this macro to
# modify the way the check is run:
#
# CMAKE_REQUIRED_FLAGS = string of compile command line flags
# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
# CMAKE_REQUIRED_INCLUDES = list of include directories
# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
#
# Extra arguments added by libarchive
# CMAKE_REQUIRED_LINKER_FLAGS = string of linker command line flags
#
include(CMakeExpandImportedTargets)
macro(LIBARCHIVE_CHECK_C_SOURCE_RUNS SOURCE VAR)
if("${VAR}" MATCHES "^${VAR}$")
set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
if(CMAKE_REQUIRED_LIBRARIES)
# this one translates potentially used imported library targets to their files on disk
CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
"-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
else()
set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
endif()
if(CMAKE_REQUIRED_INCLUDES)
set(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
else()
set(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
endif()
if(CMAKE_REQUIRED_LINKER_FLAGS)
set(CHECK_C_SOURCE_COMPILES_ADD_LINKER_FLAGS
"-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS}")
else()
set(CHECK_C_SOURCE_COMPILES_ADD_LINKER_FLAGS)
endif()
file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c"
"${SOURCE}\n")
message(STATUS "Performing Test ${VAR}")
try_run(${VAR}_EXITCODE ${VAR}_COMPILED
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} ${CHECK_C_SOURCE_COMPILES_ADD_LINKER_FLAGS}
-DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
"${CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}"
"${CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}"
COMPILE_OUTPUT_VARIABLE OUTPUT)
# if it did not compile make the return value fail code of 1
if(NOT ${VAR}_COMPILED)
set(${VAR}_EXITCODE 1)
endif()
# if the return value was 0 then it worked
if("${${VAR}_EXITCODE}" EQUAL 0)
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
message(STATUS "Performing Test ${VAR} - Success")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n"
"${OUTPUT}\n"
"Return value: ${${VAR}}\n"
"Source file was:\n${SOURCE}\n")
else()
if(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN")
set(${VAR} "${${VAR}_EXITCODE}")
else()
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
endif()
message(STATUS "Performing Test ${VAR} - Failed")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing C SOURCE FILE Test ${VAR} failed with the following output:\n"
"${OUTPUT}\n"
"Return value: ${${VAR}_EXITCODE}\n"
"Source file was:\n${SOURCE}\n")
endif()
endif()
endmacro()

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
3001002

File diff suppressed because it is too large Load diff

21631
archive/libarchive-3.1.2/configure vendored Executable file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,788 @@
dnl Process this file with autoconf to produce a configure script.
dnl First, define all of the version numbers up front.
dnl In particular, this allows the version macro to be used in AC_INIT
dnl These first two version numbers are updated automatically on each release.
m4_define([LIBARCHIVE_VERSION_S],[3.1.2])
m4_define([LIBARCHIVE_VERSION_N],[3001002])
dnl bsdtar and bsdcpio versioning tracks libarchive
m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
m4_define([BSDCPIO_VERSION_S],LIBARCHIVE_VERSION_S())
AC_PREREQ(2.65)
#
# Now starts the "real" configure script.
#
AC_INIT([libarchive],LIBARCHIVE_VERSION_S(),[libarchive-discuss@googlegroups.com])
# Make sure the srcdir contains "libarchive" directory
AC_CONFIG_SRCDIR([libarchive])
# Use auxiliary subscripts from this subdirectory (cleans up root)
AC_CONFIG_AUX_DIR([build/autoconf])
# M4 scripts
AC_CONFIG_MACRO_DIR([build/autoconf])
# Must follow AC_CONFIG macros above...
AM_INIT_AUTOMAKE()
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
# Libtool's "interface version" can be computed from the libarchive version.
# Libtool interface version bumps on any API change, so increments
# whenever libarchive minor version does.
ARCHIVE_MINOR=$(( (LIBARCHIVE_VERSION_N() / 1000) % 1000 ))
# Libarchive 2.7 == libtool interface 9 = 2 + 7
# Libarchive 2.8 == libtool interface 10 = 2 + 8
# Libarchive 2.9 == libtool interface 11 = 2 + 8
# Libarchive 3.0 == libtool interface 12
# Libarchive 3.1 == libtool interface 13
ARCHIVE_INTERFACE=`echo $((13 + ${ARCHIVE_MINOR}))`
# Libarchive revision is bumped on any source change === libtool revision
ARCHIVE_REVISION=$(( LIBARCHIVE_VERSION_N() % 1000 ))
# Libarchive minor is bumped on any interface addition === libtool age
ARCHIVE_LIBTOOL_VERSION=$ARCHIVE_INTERFACE:$ARCHIVE_REVISION:$ARCHIVE_MINOR
# Stick the version numbers into config.h
AC_DEFINE([LIBARCHIVE_VERSION_STRING],"LIBARCHIVE_VERSION_S()",
[Version number of libarchive])
AC_DEFINE_UNQUOTED([LIBARCHIVE_VERSION_NUMBER],"LIBARCHIVE_VERSION_N()",
[Version number of libarchive as a single integer])
AC_DEFINE([BSDCPIO_VERSION_STRING],"BSDCPIO_VERSION_S()",
[Version number of bsdcpio])
AC_DEFINE([BSDTAR_VERSION_STRING],"BSDTAR_VERSION_S()",
[Version number of bsdtar])
# The shell variables here must be the same as the AC_SUBST() variables
# below, but the shell variable names apparently cannot be the same as
# the m4 macro names above. Why? Ask autoconf.
BSDCPIO_VERSION_STRING=BSDCPIO_VERSION_S()
BSDTAR_VERSION_STRING=BSDTAR_VERSION_S()
LIBARCHIVE_VERSION_STRING=LIBARCHIVE_VERSION_S()
LIBARCHIVE_VERSION_NUMBER=LIBARCHIVE_VERSION_N()
# Substitute the above version numbers into the various files below.
# Yes, I believe this is the fourth time we define what are essentially
# the same symbols. Why? Ask autoconf.
AC_SUBST(ARCHIVE_LIBTOOL_VERSION)
AC_SUBST(BSDCPIO_VERSION_STRING)
AC_SUBST(BSDTAR_VERSION_STRING)
AC_SUBST(LIBARCHIVE_VERSION_STRING)
AC_SUBST(LIBARCHIVE_VERSION_NUMBER)
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile])
AC_CONFIG_FILES([build/pkgconfig/libarchive.pc])
# Check for host type
AC_CANONICAL_HOST
dnl Compilation on mingw and Cygwin needs special Makefile rules
inc_windows_files=no
inc_cygwin_files=no
case "$host_os" in
*mingw* ) inc_windows_files=yes ;;
*cygwin*) inc_cygwin_files=yes ;;
esac
AM_CONDITIONAL([INC_WINDOWS_FILES], [test $inc_windows_files = yes])
AM_CONDITIONAL([INC_CYGWIN_FILES], [test $inc_cygwin_files = yes])
dnl Defines that are required for specific platforms (e.g. -D_POSIX_SOURCE, etc)
PLATFORMCPPFLAGS=
case "$host_os" in
*mingw* ) PLATFORMCPPFLAGS=-D__USE_MINGW_ANSI_STDIO ;;
esac
AC_SUBST(PLATFORMCPPFLAGS)
# Checks for programs.
AC_PROG_CC
AM_PROG_CC_C_O
AC_USE_SYSTEM_EXTENSIONS
AC_LIBTOOL_WIN32_DLL
AC_PROG_LIBTOOL
AC_CHECK_TOOL([STRIP],[strip])
#
# Options for building bsdtar.
#
# Default is to build bsdtar, but allow people to override that.
#
AC_ARG_ENABLE([bsdtar],
[AS_HELP_STRING([--enable-bsdtar], [enable build of bsdtar (default)])
AS_HELP_STRING([--enable-bsdtar=static], [force static build of bsdtar])
AS_HELP_STRING([--enable-bsdtar=shared], [force dynamic build of bsdtar])
AS_HELP_STRING([--disable-bsdtar], [disable build of bsdtar])],
[], [enable_bsdtar=yes])
case "$enable_bsdtar" in
yes)
if test "$enable_static" = "no"; then
static_bsdtar=no
else
static_bsdtar=yes
fi
build_bsdtar=yes
;;
dynamic|shared)
if test "$enable_shared" = "no"; then
AC_MSG_FAILURE([Shared linking of bsdtar requires shared libarchive])
fi
build_bsdtar=yes
static_bsdtar=no
;;
static)
build_bsdtar=yes
static_bsdtar=yes
;;
no)
build_bsdtar=no
static_bsdtar=no
;;
*)
AC_MSG_FAILURE([Unsupported value for --enable-bsdtar])
;;
esac
AM_CONDITIONAL([BUILD_BSDTAR], [ test "$build_bsdtar" = yes ])
AM_CONDITIONAL([STATIC_BSDTAR], [ test "$static_bsdtar" = yes ])
#
# Options for building bsdcpio.
#
# Default is not to build bsdcpio, but that can be overridden.
#
AC_ARG_ENABLE([bsdcpio],
[AS_HELP_STRING([--enable-bsdcpio], [enable build of bsdcpio (default)])
AS_HELP_STRING([--enable-bsdcpio=static], [static build of bsdcpio])
AS_HELP_STRING([--enable-bsdcpio=shared], [dynamic build of bsdcpio])
AS_HELP_STRING([--disable-bsdcpio], [disable build of bsdcpio])],
[], [enable_bsdcpio=yes])
case "$enable_bsdcpio" in
yes)
if test "$enable_static" = "no"; then
static_bsdcpio=no
else
static_bsdcpio=yes
fi
build_bsdcpio=yes
;;
dynamic|shared)
if test "$enabled_shared" = "no"; then
AC_MSG_FAILURE([Shared linking of bsdcpio requires shared libarchive])
fi
build_bsdcpio=yes
;;
static)
build_bsdcpio=yes
static_bsdcpio=yes
;;
no)
build_bsdcpio=no
static_bsdcpio=no
;;
*)
AC_MSG_FAILURE([Unsupported value for --enable-bsdcpio])
;;
esac
AM_CONDITIONAL([BUILD_BSDCPIO], [ test "$build_bsdcpio" = yes ])
AM_CONDITIONAL([STATIC_BSDCPIO], [ test "$static_bsdcpio" = yes ])
# Set up defines needed before including any headers
case $host in
*mingw* | *cygwin* )
AC_DEFINE([_WIN32_WINNT], 0x0500, [Define to '0x0500' for Windows 2000 APIs.])
AC_DEFINE([WINVER], 0x0500, [Define to '0x0500' for Windows 2000 APIs.])
;;
esac
# Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS([acl/libacl.h attr/xattr.h copyfile.h ctype.h])
AC_CHECK_HEADERS([errno.h ext2fs/ext2_fs.h fcntl.h grp.h])
AC_CACHE_CHECK([whether EXT2_IOC_GETFLAGS is usable],
[ac_cv_have_decl_EXT2_IOC_GETFLAGS],
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([@%:@include <sys/ioctl.h>
@%:@include <ext2fs/ext2_fs.h>],
[int x = EXT2_IOC_GETFLAGS])],
[AS_VAR_SET([ac_cv_have_decl_EXT2_IOC_GETFLAGS], [yes])],
[AS_VAR_SET([ac_cv_have_decl_EXT2_IOC_GETFLAGS], [no])])])
AS_VAR_IF([ac_cv_have_decl_EXT2_IOC_GETFLAGS], [yes],
[AC_DEFINE_UNQUOTED([HAVE_WORKING_EXT2_IOC_GETFLAGS], [1],
[Define to 1 if you have a working EXT2_IOC_GETFLAGS])])
AC_CHECK_HEADERS([inttypes.h io.h langinfo.h limits.h])
AC_CHECK_HEADERS([linux/fiemap.h linux/fs.h linux/magic.h linux/types.h])
AC_CHECK_HEADERS([locale.h paths.h poll.h pwd.h signal.h spawn.h])
AC_CHECK_HEADERS([stdarg.h stdint.h stdlib.h string.h])
AC_CHECK_HEADERS([sys/acl.h sys/cdefs.h sys/extattr.h])
AC_CHECK_HEADERS([sys/ioctl.h sys/mkdev.h sys/mount.h])
AC_CHECK_HEADERS([sys/param.h sys/poll.h sys/select.h sys/statfs.h sys/statvfs.h])
AC_CHECK_HEADERS([sys/time.h sys/utime.h sys/utsname.h sys/vfs.h])
AC_CHECK_HEADERS([time.h unistd.h utime.h wchar.h wctype.h])
AC_CHECK_HEADERS([windows.h])
# check windows.h first; the other headers require it.
AC_CHECK_HEADERS([wincrypt.h winioctl.h],[],[],
[[#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
]])
# Checks for libraries.
AC_ARG_WITH([zlib],
AS_HELP_STRING([--without-zlib], [Don't build support for gzip through zlib]))
if test "x$with_zlib" != "xno"; then
AC_CHECK_HEADERS([zlib.h])
AC_CHECK_LIB(z,inflate)
fi
AC_ARG_WITH([bz2lib],
AS_HELP_STRING([--without-bz2lib], [Don't build support for bzip2 through bz2lib]))
if test "x$with_bz2lib" != "xno"; then
AC_CHECK_HEADERS([bzlib.h])
case "$host_os" in
*mingw* | *cygwin*)
dnl AC_CHECK_LIB cannot be used on the Windows port of libbz2, therefore
dnl use AC_LINK_IFELSE.
AC_MSG_CHECKING([for BZ2_bzDecompressInit in -lbz2])
old_LIBS="$LIBS"
LIBS="-lbz2 $LIBS"
AC_LINK_IFELSE(
[AC_LANG_SOURCE(#include <bzlib.h>
int main() { return BZ2_bzDecompressInit(NULL, 0, 0); })],
[ac_cv_lib_bz2_BZ2_bzDecompressInit=yes],
[ac_cv_lib_bz2_BZ2_bzDecompressInit=no])
LIBS="$old_LIBS"
AC_MSG_RESULT($ac_cv_lib_bz2_BZ2_bzDecompressInit)
if test "x$ac_cv_lib_bz2_BZ2_bzDecompressInit" = xyes; then
AC_DEFINE([HAVE_LIBBZ2], [1], [Define to 1 if you have the `bz2' library (-lbz2).])
LIBS="-lbz2 $LIBS"
fi
;;
*)
AC_CHECK_LIB(bz2,BZ2_bzDecompressInit)
;;
esac
fi
AC_ARG_WITH([lzmadec],
AS_HELP_STRING([--without-lzmadec], [Don't build support for lzma through lzmadec]))
if test "x$with_lzmadec" != "xno"; then
AC_CHECK_HEADERS([lzmadec.h])
AC_CHECK_LIB(lzmadec,lzmadec_decode)
fi
AC_ARG_WITH([iconv],
AS_HELP_STRING([--without-iconv], [Don't try to link against iconv]))
if test "x$with_iconv" != "xno"; then
AM_ICONV
AC_CHECK_HEADERS([iconv.h],[],[],[#include <stdlib.h>])
if test "x$am_cv_func_iconv" = "xyes"; then
AC_CHECK_HEADERS([localcharset.h])
am_save_LIBS="$LIBS"
LIBS="${LIBS} ${LIBICONV}"
AC_CHECK_FUNCS([locale_charset])
LIBS="${am_save_LIBS}"
if test "x$ac_cv_func_locale_charset" != "xyes"; then
# If locale_charset() is not in libiconv, we have to find libcharset.
AC_CHECK_LIB(charset,locale_charset)
fi
fi
fi
AC_ARG_WITH([lzma],
AS_HELP_STRING([--without-lzma], [Don't build support for xz through lzma]))
if test "x$with_lzma" != "xno"; then
AC_CHECK_HEADERS([lzma.h])
AC_CHECK_LIB(lzma,lzma_stream_decoder)
fi
AC_ARG_WITH([lzo2],
AS_HELP_STRING([--without-lzo2], [Don't build support for lzop through liblzo2]))
if test "x$with_lzo2" != "xno"; then
AC_CHECK_HEADERS([lzo/lzoconf.h lzo/lzo1x.h])
AC_CHECK_LIB(lzo2,lzo1x_decompress_safe)
fi
AC_ARG_WITH([nettle],
AS_HELP_STRING([--without-nettle], [Don't build with crypto support from Nettle]))
AC_ARG_WITH([openssl],
AS_HELP_STRING([--without-openssl], [Don't build support for mtree and xar hashes through openssl]))
case "$host_os" in
*darwin* ) with_openssl=no ;;
esac
AC_ARG_WITH([xml2],
AS_HELP_STRING([--without-xml2], [Don't build support for xar through libxml2]))
AC_ARG_WITH([expat],
AS_HELP_STRING([--without-expat], [Don't build support for xar through expat]))
if test "x$with_xml2" != "xno"; then
AC_PATH_PROG([XML2_CONFIG], [xml2-config],, [${PATH}])
if test "x$XML2_CONFIG" != "x"; then
CPPFLAGS="${CPPFLAGS} `${XML2_CONFIG} --cflags`"
LIBS="${LIBS} `${XML2_CONFIG} --libs`"
AC_CHECK_LIB(xml2,xmlInitParser,[true],AC_MSG_FAILURE(Missing xml2 library))
else
AC_CHECK_LIB(xml2,xmlInitParser)
fi
AC_CHECK_HEADERS([libxml/xmlreader.h libxml/xmlwriter.h])
fi
if test "x$ac_cv_header_libxml_xmlreader_h" != "xyes"; then
if test "x$with_expat" != "xno"; then
AC_CHECK_HEADERS([expat.h])
AC_CHECK_LIB(expat,XML_ParserCreate)
fi
fi
AC_ARG_ENABLE([posix-regex-lib],
[AS_HELP_STRING([--enable-posix-regex-lib],
[choose what library to use for POSIX regular expression support (default: auto)])
AS_HELP_STRING([--enable-posix-regex-lib=libc], [use libc POSIX regular expression support])
AS_HELP_STRING([--enable-posix-regex-lib=libregex], [use libregex POSIX regular expression support])
AS_HELP_STRING([--enable-posix-regex-lib=libpcreposix], [use libpcreposix POSIX regular expression support])
AS_HELP_STRING([--disable-posix-regex-lib], [don't enable POSIX regular expression support])],
[], [enable_posix_regex_lib=auto])
posix_regex_lib_found=
if test "$enable_posix_regex_lib" = "auto" || test "$enable_posix_regex_lib" = "libc" || test "$enable_posix_regex_lib" = "libregex"; then
AC_CHECK_HEADERS([regex.h])
if test "x$ac_cv_header_regex_h" != "xno"; then
AC_CHECK_FUNC(regcomp)
if test "x$ac_cv_func_regcomp" = xyes; then
posix_regex_lib_found=1
else
AC_CHECK_LIB(regex,regcomp)
if test "x$ac_cv_lib_regex_regcomp" = xyes; then
posix_regex_lib_found=1
fi
fi
fi
fi
if test -z $posix_regex_lib_found && (test "$enable_posix_regex_lib" = "auto" || test "$enable_posix_regex_lib" = "libpcreposix"); then
AC_CHECK_HEADERS([pcreposix.h])
AC_CHECK_LIB(pcreposix,regcomp)
if test "x$ac_cv_lib_pcreposix_regcomp" != xyes; then
AC_MSG_NOTICE(trying libpcreposix check again with libpcre)
unset ac_cv_lib_pcreposix_regcomp
AC_CHECK_LIB(pcre,pcre_exec)
AC_CHECK_LIB(pcreposix,regcomp)
if test "x$ac_cv_lib_pcre_pcre_exec" = xyes && test "x$ac_cv_lib_pcreposix_regcomp" = xyes; then
AC_MSG_CHECKING(if PCRE_STATIC needs to be defined)
AC_LINK_IFELSE(
[AC_LANG_SOURCE(#include <pcreposix.h>
int main() { return regcomp(NULL, NULL, 0); })],
[without_pcre_static=yes],
[without_pcre_static=no])
AC_LINK_IFELSE(
[AC_LANG_SOURCE(#define PCRE_STATIC
#include <pcreposix.h>
int main() { return regcomp(NULL, NULL, 0); })],
[with_pcre_static=yes],
[with_pcre_static=no])
if test "x$without_pcre_static" != xyes && test "x$with_pcre_static" = xyes; then
AC_MSG_RESULT(yes)
AC_DEFINE([PCRE_STATIC], [1], [Define to 1 if PCRE_STATIC needs to be defined.])
elif test "x$without_pcre_static" = xyes || test "x$with_pcre_static" = xyes; then
AC_MSG_RESULT(no)
fi
posix_regex_lib_found=1
fi
else
posix_regex_lib_found=1
fi
fi
# TODO: Give the user the option of using a pre-existing system
# libarchive. This will define HAVE_LIBARCHIVE which will cause
# bsdtar_platform.h to use #include <...> for the libarchive headers.
# Need to include Makefile.am magic to link against system
# -larchive in that case.
#AC_CHECK_LIB(archive,archive_version)
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
# AC_TYPE_UID_T defaults to "int", which is incorrect for MinGW
# and MSVC. Use a customized version.
la_TYPE_UID_T
AC_TYPE_MODE_T
# AC_TYPE_OFF_T defaults to "long", which limits us to 4GB files on
# most systems... default to "long long" instead.
AC_CHECK_TYPE(off_t, [long long])
AC_TYPE_SIZE_T
AC_CHECK_TYPE(id_t, [unsigned long])
AC_CHECK_TYPE(uintptr_t, [unsigned int])
# Check for tm_gmtoff in struct tm
AC_CHECK_MEMBERS([struct tm.tm_gmtoff, struct tm.__tm_gmtoff],,,
[
#include <time.h>
])
# Check for f_namemax in struct statfs
AC_CHECK_MEMBERS([struct statfs.f_namemax],,,
[
#include <sys/param.h>
#include <sys/mount.h>
])
# Check for f_iosize in struct statvfs
AC_CHECK_MEMBERS([struct statvfs.f_iosize],,,
[
#include <sys/statvfs.h>
])
# Check for birthtime in struct stat
AC_CHECK_MEMBERS([struct stat.st_birthtime])
# Check for high-resolution timestamps in struct stat
AC_CHECK_MEMBERS([struct stat.st_birthtimespec.tv_nsec])
AC_CHECK_MEMBERS([struct stat.st_mtimespec.tv_nsec])
AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec])
AC_CHECK_MEMBERS([struct stat.st_mtime_n]) # AIX
AC_CHECK_MEMBERS([struct stat.st_umtime]) # Tru64
AC_CHECK_MEMBERS([struct stat.st_mtime_usec]) # Hurd
# Check for block size support in struct stat
AC_CHECK_MEMBERS([struct stat.st_blksize])
# Check for st_flags in struct stat (BSD fflags)
AC_CHECK_MEMBERS([struct stat.st_flags])
# If you have uintmax_t, we assume printf supports %ju
# If you have unsigned long long, we assume printf supports %llu
# TODO: Check for %ju and %llu support directly.
AC_CHECK_TYPES([uintmax_t, unsigned long long])
# We use C99-style integer types
# Declare them if the local platform doesn't already do so.
AC_TYPE_INTMAX_T
AC_TYPE_UINTMAX_T
AC_TYPE_INT64_T
AC_TYPE_UINT64_T
AC_TYPE_INT32_T
AC_TYPE_UINT32_T
AC_TYPE_INT16_T
AC_TYPE_UINT16_T
AC_TYPE_UINT8_T
AC_CHECK_DECLS([SIZE_MAX, INT64_MAX, INT64_MIN, UINT64_MAX, UINT32_MAX])
AC_CHECK_DECL([SSIZE_MAX],
[AC_DEFINE(HAVE_DECL_SSIZE_MAX, 1, [Define to 1 if you have the declaration of `SSIZE_MAX', and to 0 if you don't.])],
[],
[#include <limits.h>])
AC_CHECK_DECL([EFTYPE],
[AC_DEFINE(HAVE_EFTYPE, 1, [A possible errno value for invalid file format errors])],
[],
[#include <errno.h>])
AC_CHECK_DECL([EILSEQ],
[AC_DEFINE(HAVE_EILSEQ, 1, [A possible errno value for invalid file format errors])],
[],
[#include <errno.h>])
AC_CHECK_TYPE([wchar_t],
[AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_[]wchar_t), 1, [Define to 1 if the system has the type `wchar_t'.])dnl
AC_CHECK_SIZEOF([wchar_t])],
[])
AC_HEADER_TIME
# Checks for library functions.
AC_PROG_GCC_TRADITIONAL
AC_HEADER_MAJOR
AC_FUNC_FSEEKO
AC_FUNC_MEMCMP
AC_FUNC_LSTAT
AC_FUNC_STAT
AC_FUNC_STRERROR_R
AC_FUNC_STRFTIME
AC_FUNC_VPRINTF
# check for:
# CreateHardLinkA(LPCSTR, LPCSTR, LPSECURITY_ATTRIBUTES)
# To avoid necessity for including windows.h or special forward declaration
# workarounds, we use 'void *' for 'struct SECURITY_ATTRIBUTES *'
AC_CHECK_STDCALL_FUNC([CreateHardLinkA],[const char *, const char *, void *])
AC_CHECK_FUNCS([chflags chown chroot ctime_r dirfd])
AC_CHECK_FUNCS([fchdir fchflags fchmod fchown fcntl fdopendir fork])
AC_CHECK_FUNCS([fstat fstatat fstatfs fstatvfs ftruncate])
AC_CHECK_FUNCS([futimens futimes futimesat])
AC_CHECK_FUNCS([geteuid getpid getgrgid_r getgrnam_r])
AC_CHECK_FUNCS([getpwnam_r getpwuid_r getvfsbyname gmtime_r])
AC_CHECK_FUNCS([lchflags lchmod lchown link localtime_r lstat lutimes])
AC_CHECK_FUNCS([mbrtowc memmove memset])
AC_CHECK_FUNCS([mkdir mkfifo mknod mkstemp])
AC_CHECK_FUNCS([nl_langinfo openat pipe poll posix_spawnp readlink readlinkat])
AC_CHECK_FUNCS([select setenv setlocale sigaction statfs statvfs])
AC_CHECK_FUNCS([strchr strdup strerror strncpy_s strrchr symlink timegm])
AC_CHECK_FUNCS([tzset unsetenv utime utimensat utimes vfork])
AC_CHECK_FUNCS([wcrtomb wcscmp wcscpy wcslen wctomb wmemcmp wmemcpy])
AC_CHECK_FUNCS([_ctime64_s _fseeki64])
AC_CHECK_FUNCS([_get_timezone _localtime64_s _mkgmtime64])
# detects cygwin-1.7, as opposed to older versions
AC_CHECK_FUNCS([cygwin_conv_path])
# There are several variants of readdir_r around; we only
# accept the POSIX-compliant version.
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([[#include <dirent.h>]],
[[DIR *dir; struct dirent e, *r;
return(readdir_r(dir, &e, &r));]])],
[AC_DEFINE(HAVE_READDIR_R,1,[Define to 1 if you have a POSIX compatible readdir_r])]
)
# FreeBSD's nl_langinfo supports an option to specify whether the
# current locale uses month/day or day/month ordering. It makes the
# output a little prettier...
AC_CHECK_DECL([D_MD_ORDER],
[AC_DEFINE(HAVE_D_MD_ORDER, 1, [Define to 1 if nl_langinfo supports D_MD_ORDER])],
[],
[#if HAVE_LANGINFO_H
#include <langinfo.h>
#endif
])
# Check for dirent.d_namlen field explicitly
# (This is a bit more straightforward than, if not quite as portable as,
# the recipe given by the autoconf maintainers.)
AC_CHECK_MEMBER(struct dirent.d_namlen,,,
[#if HAVE_DIRENT_H
#include <dirent.h>
#endif
])
# Check for Extended Attributes support
AC_ARG_ENABLE([xattr],
AS_HELP_STRING([--disable-xattr],
[Enable Extended Attributes support (default: check)]))
if test "x$enable_xattr" != "xno"; then
AC_CHECK_HEADERS([attr/xattr.h])
AC_CHECK_HEADERS([sys/xattr.h sys/ea.h])
AC_CHECK_LIB(attr,setxattr)
AC_CHECK_FUNCS([extattr_get_file extattr_list_file])
AC_CHECK_FUNCS([extattr_set_fd extattr_set_file])
AC_CHECK_FUNCS([fgetxattr flistxattr fsetxattr getxattr])
AC_CHECK_FUNCS([lgetxattr listxattr llistxattr lsetxattr])
AC_CHECK_FUNCS([fgetea flistea fsetea getea])
AC_CHECK_FUNCS([lgetea listea llistea lsetea])
AC_CHECK_DECLS([EXTATTR_NAMESPACE_USER], [], [], [#include <sys/types.h>
#include <sys/extattr.h>
])
fi
# Check for ACL support
#
# The ACL support in libarchive is written against the POSIX1e draft,
# which was never officially approved and varies quite a bit across
# platforms. Worse, some systems have completely non-POSIX acl functions,
# which makes the following checks rather more complex than I would like.
#
AC_ARG_ENABLE([acl],
AS_HELP_STRING([--disable-acl],
[Enable ACL support (default: check)]))
if test "x$enable_acl" != "xno"; then
AC_CHECK_HEADERS([sys/acl.h])
AC_CHECK_LIB([acl],[acl_get_file])
AC_CHECK_FUNCS([acl_create_entry acl_init acl_set_fd acl_set_fd_np acl_set_file])
AC_CHECK_TYPES(acl_permset_t,,,
[#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if HAVE_SYS_ACL_H
#include <sys/acl.h>
#endif
])
# The "acl_get_perm()" function was omitted from the POSIX draft.
# (It's a pretty obvious oversight; otherwise, there's no way to
# test for specific permissions in a permset.) Linux uses the obvious
# name, FreeBSD adds _np to mark it as "non-Posix extension."
# Test for both as a double-check that we really have POSIX-style ACL support.
AC_CHECK_FUNCS(acl_get_perm_np acl_get_perm acl_get_link acl_get_link_np,,,
[#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if HAVE_SYS_ACL_H
#include <sys/acl.h>
#endif
])
# MacOS has an acl.h that isn't POSIX. It can be detected by
# checking for ACL_USER
AC_CHECK_DECL([ACL_USER],
[AC_DEFINE(HAVE_ACL_USER, 1, [True for systems with POSIX ACL support])],
[],
[#include <sys/acl.h>])
fi
# Additional requirements
AC_SYS_LARGEFILE
dnl NOTE: Crypto checks must run last.
AC_DEFUN([CRYPTO_CHECK], [
if test "$found_$1" != yes; then
saved_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive"
touch "check_crypto_md.h"
AC_MSG_CHECKING([support for ARCHIVE_CRYPTO_$1_$2])
AC_LINK_IFELSE([AC_LANG_SOURCE([
#define ARCHIVE_$1_COMPILE_TEST
#define ARCHIVE_CRYPTO_$1_$2
#define PLATFORM_CONFIG_H "check_crypto_md.h"
$(cat "$srcdir/libarchive/archive_crypto.c")
int
main(int argc, char **argv)
{
archive_$3_ctx ctx;
archive_$3_init(&ctx);
archive_$3_update(&ctx, *argv, argc);
archive_$3_final(&ctx, NULL);
return 0;
}
])],
[ AC_MSG_RESULT([yes])
found_$1=yes
found_$2=yes
AC_DEFINE(ARCHIVE_CRYPTO_$1_$2, 1, [ $1 via ARCHIVE_CRYPTO_$1_$2 supported.])
],
[ AC_MSG_RESULT([no])])
CPPFLAGS="$saved_CPPFLAGS"
rm "check_crypto_md.h"
fi
])
AC_DEFUN([CRYPTO_CHECK_WIN], [
if test "$found_$1" != yes; then
AC_MSG_CHECKING([support for ARCHIVE_CRYPTO_$1_WIN])
AC_LINK_IFELSE([AC_LANG_SOURCE([
#define ARCHIVE_$1_COMPILE_TEST
#include <windows.h>
#include <wincrypt.h>
int
main(int argc, char **argv)
{
(void)argc;
(void)argv;
return ($2);
}
])],
[ AC_MSG_RESULT([yes])
found_$1=yes
found_WIN=yes
AC_DEFINE(ARCHIVE_CRYPTO_$1_WIN, 1, [ $1 via ARCHIVE_CRYPTO_$1_WIN supported.])
],
[ AC_MSG_RESULT([no])])
fi
])
case "$host_os" in
*mingw* | *cygwin*)
;;
*)
CRYPTO_CHECK(MD5, LIBC, md5)
CRYPTO_CHECK(MD5, LIBSYSTEM, md5)
CRYPTO_CHECK(RMD160, LIBC, rmd160)
CRYPTO_CHECK(SHA1, LIBC, sha1)
CRYPTO_CHECK(SHA1, LIBSYSTEM, sha1)
CRYPTO_CHECK(SHA256, LIBC, sha256)
CRYPTO_CHECK(SHA256, LIBC2, sha256)
CRYPTO_CHECK(SHA256, LIBC3, sha256)
CRYPTO_CHECK(SHA256, LIBSYSTEM, sha256)
CRYPTO_CHECK(SHA384, LIBC, sha384)
CRYPTO_CHECK(SHA384, LIBC2, sha384)
CRYPTO_CHECK(SHA384, LIBC3, sha384)
CRYPTO_CHECK(SHA384, LIBSYSTEM, sha384)
CRYPTO_CHECK(SHA512, LIBC, sha512)
CRYPTO_CHECK(SHA512, LIBC2, sha512)
CRYPTO_CHECK(SHA512, LIBC3, sha512)
CRYPTO_CHECK(SHA512, LIBSYSTEM, sha512)
;;
esac
if test "x$with_nettle" != "xno"; then
AC_CHECK_HEADERS([nettle/md5.h nettle/ripemd160.h nettle/sha.h])
saved_LIBS=$LIBS
AC_CHECK_LIB(nettle,main)
CRYPTO_CHECK(MD5, NETTLE, md5)
CRYPTO_CHECK(RMD160, NETTLE, rmd160)
CRYPTO_CHECK(SHA1, NETTLE, sha1)
CRYPTO_CHECK(SHA256, NETTLE, sha256)
CRYPTO_CHECK(SHA384, NETTLE, sha384)
CRYPTO_CHECK(SHA512, NETTLE, sha512)
if test "x$found_NETTLE" != "xyes"; then
LIBS=$saved_LIBS
fi
fi
if test "x$with_openssl" != "xno"; then
AC_CHECK_HEADERS([openssl/evp.h])
saved_LIBS=$LIBS
case "$host_os" in
*mingw* | *cygwin*)
case "$host_cpu" in
x86_64)
AC_CHECK_LIB(eay64,main)
if test "x$ac_cv_lib_eay64_main" != "xyes"; then
AC_CHECK_LIB(eay32,main)
fi
;;
*)
AC_CHECK_LIB(eay32,main)
;;
esac
;;
*)
AC_CHECK_LIB(crypto,main)
;;
esac
CRYPTO_CHECK(MD5, OPENSSL, md5)
CRYPTO_CHECK(RMD160, OPENSSL, rmd160)
CRYPTO_CHECK(SHA1, OPENSSL, sha1)
CRYPTO_CHECK(SHA256, OPENSSL, sha256)
CRYPTO_CHECK(SHA384, OPENSSL, sha384)
CRYPTO_CHECK(SHA512, OPENSSL, sha512)
if test "x$found_OPENSSL" != "xyes"; then
LIBS=$saved_LIBS
fi
fi
# Probe libmd AFTER OpenSSL/libcrypto.
# The two are incompatible and OpenSSL is more complete.
AC_CHECK_HEADERS([md5.h ripemd.h sha.h sha256.h sha512.h])
saved_LIBS=$LIBS
AC_CHECK_LIB(md,main)
CRYPTO_CHECK(MD5, LIBMD, md5)
CRYPTO_CHECK(RMD160, LIBMD, rmd160)
CRYPTO_CHECK(SHA1, LIBMD, sha1)
CRYPTO_CHECK(SHA256, LIBMD, sha256)
CRYPTO_CHECK(SHA512, LIBMD, sha512)
if test "x$found_LIBMD" != "xyes"; then
LIBS=$saved_LIBS
fi
case "$host_os" in
*mingw* | *cygwin*)
CRYPTO_CHECK_WIN(MD5, CALG_MD5)
CRYPTO_CHECK_WIN(SHA1, CALG_SHA1)
CRYPTO_CHECK_WIN(SHA256, CALG_SHA_256)
CRYPTO_CHECK_WIN(SHA384, CALG_SHA_384)
CRYPTO_CHECK_WIN(SHA512, CALG_SHA_512)
;;
esac
AC_OUTPUT

View file

@ -0,0 +1,193 @@
############################################
#
# How to build libarchive
#
############################################
# Public headers
SET(include_HEADERS
archive.h
archive_entry.h
)
# Sources and private headers
SET(libarchive_SOURCES
archive_acl.c
archive_check_magic.c
archive_cmdline.c
archive_cmdline_private.h
archive_crc32.h
archive_crypto.c
archive_crypto_private.h
archive_endian.h
archive_entry.c
archive_entry.h
archive_entry_copy_stat.c
archive_entry_link_resolver.c
archive_entry_locale.h
archive_entry_private.h
archive_entry_sparse.c
archive_entry_stat.c
archive_entry_strmode.c
archive_entry_xattr.c
archive_getdate.c
archive_match.c
archive_options.c
archive_options_private.h
archive_pathmatch.c
archive_pathmatch.h
archive_platform.h
archive_ppmd_private.h
archive_ppmd7.c
archive_ppmd7_private.h
archive_private.h
archive_rb.c
archive_rb.h
archive_read.c
archive_read_append_filter.c
archive_read_data_into_fd.c
archive_read_disk_entry_from_file.c
archive_read_disk_posix.c
archive_read_disk_private.h
archive_read_disk_set_standard_lookup.c
archive_read_extract.c
archive_read_open_fd.c
archive_read_open_file.c
archive_read_open_filename.c
archive_read_open_memory.c
archive_read_private.h
archive_read_set_format.c
archive_read_set_options.c
archive_read_support_filter_all.c
archive_read_support_filter_bzip2.c
archive_read_support_filter_compress.c
archive_read_support_filter_gzip.c
archive_read_support_filter_grzip.c
archive_read_support_filter_lrzip.c
archive_read_support_filter_lzop.c
archive_read_support_filter_none.c
archive_read_support_filter_program.c
archive_read_support_filter_rpm.c
archive_read_support_filter_uu.c
archive_read_support_filter_xz.c
archive_read_support_format_7zip.c
archive_read_support_format_all.c
archive_read_support_format_ar.c
archive_read_support_format_by_code.c
archive_read_support_format_cab.c
archive_read_support_format_cpio.c
archive_read_support_format_empty.c
archive_read_support_format_iso9660.c
archive_read_support_format_lha.c
archive_read_support_format_mtree.c
archive_read_support_format_rar.c
archive_read_support_format_raw.c
archive_read_support_format_tar.c
archive_read_support_format_xar.c
archive_read_support_format_zip.c
archive_string.c
archive_string.h
archive_string_composition.h
archive_string_sprintf.c
archive_util.c
archive_virtual.c
archive_write.c
archive_write_disk_acl.c
archive_write_disk_posix.c
archive_write_disk_private.h
archive_write_disk_set_standard_lookup.c
archive_write_private.h
archive_write_open_fd.c
archive_write_open_file.c
archive_write_open_filename.c
archive_write_open_memory.c
archive_write_add_filter.c
archive_write_add_filter_b64encode.c
archive_write_add_filter_by_name.c
archive_write_add_filter_bzip2.c
archive_write_add_filter_compress.c
archive_write_add_filter_grzip.c
archive_write_add_filter_gzip.c
archive_write_add_filter_lrzip.c
archive_write_add_filter_lzop.c
archive_write_add_filter_none.c
archive_write_add_filter_program.c
archive_write_add_filter_uuencode.c
archive_write_add_filter_xz.c
archive_write_set_format.c
archive_write_set_format_7zip.c
archive_write_set_format_ar.c
archive_write_set_format_by_name.c
archive_write_set_format_cpio.c
archive_write_set_format_cpio_newc.c
archive_write_set_format_gnutar.c
archive_write_set_format_iso9660.c
archive_write_set_format_mtree.c
archive_write_set_format_pax.c
archive_write_set_format_shar.c
archive_write_set_format_ustar.c
archive_write_set_format_v7tar.c
archive_write_set_format_xar.c
archive_write_set_format_zip.c
archive_write_set_options.c
filter_fork_posix.c
filter_fork.h
)
# Man pages
SET(libarchive_MANS
archive_entry.3
archive_entry_acl.3
archive_entry_linkify.3
archive_entry_paths.3
archive_entry_perms.3
archive_entry_stat.3
archive_entry_time.3
archive_read.3
archive_read_disk.3
archive_read_set_options.3
archive_util.3
archive_write.3
archive_write_disk.3
archive_write_set_options.3
cpio.5
libarchive.3
libarchive_internals.3
libarchive-formats.5
mtree.5
tar.5
)
IF(WIN32 AND NOT CYGWIN)
LIST(APPEND libarchive_SOURCES archive_entry_copy_bhfi.c)
LIST(APPEND libarchive_SOURCES archive_read_disk_windows.c)
LIST(APPEND libarchive_SOURCES archive_windows.c)
LIST(APPEND libarchive_SOURCES archive_windows.h)
LIST(APPEND libarchive_SOURCES archive_write_disk_windows.c)
LIST(APPEND libarchive_SOURCES filter_fork_windows.c)
ENDIF(WIN32 AND NOT CYGWIN)
# Libarchive is a shared library
ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS})
TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS})
SET_TARGET_PROPERTIES(archive PROPERTIES SOVERSION ${SOVERSION})
# archive_static is a static library
ADD_LIBRARY(archive_static STATIC ${libarchive_SOURCES} ${include_HEADERS})
SET_TARGET_PROPERTIES(archive_static PROPERTIES COMPILE_DEFINITIONS
LIBARCHIVE_STATIC)
# On Posix systems, libarchive.so and libarchive.a can co-exist.
IF(NOT WIN32 OR CYGWIN)
SET_TARGET_PROPERTIES(archive_static PROPERTIES OUTPUT_NAME archive)
ENDIF(NOT WIN32 OR CYGWIN)
# How to install the libraries
INSTALL(TARGETS archive archive_static
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
INSTALL_MAN(${libarchive_MANS})
INSTALL(FILES ${include_HEADERS} DESTINATION include)
add_subdirectory(test)

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,87 @@
/*-
* Copyright (c) 2003-2010 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_ACL_PRIVATE_H_INCLUDED
#define ARCHIVE_ACL_PRIVATE_H_INCLUDED
#include "archive_string.h"
struct archive_acl_entry {
struct archive_acl_entry *next;
int type; /* E.g., access or default */
int tag; /* E.g., user/group/other/mask */
int permset; /* r/w/x bits */
int id; /* uid/gid for user/group */
struct archive_mstring name; /* uname/gname */
};
struct archive_acl {
mode_t mode;
struct archive_acl_entry *acl_head;
struct archive_acl_entry *acl_p;
int acl_state; /* See acl_next for details. */
wchar_t *acl_text_w;
char *acl_text;
int acl_types;
};
void archive_acl_clear(struct archive_acl *);
void archive_acl_copy(struct archive_acl *, struct archive_acl *);
int archive_acl_count(struct archive_acl *, int);
int archive_acl_reset(struct archive_acl *, int);
int archive_acl_next(struct archive *, struct archive_acl *, int,
int *, int *, int *, int *, const char **);
int archive_acl_add_entry(struct archive_acl *, int, int, int, int, const char *);
int archive_acl_add_entry_w_len(struct archive_acl *,
int, int, int, int, const wchar_t *, size_t);
int archive_acl_add_entry_len(struct archive_acl *,
int, int, int, int, const char *, size_t);
const wchar_t *archive_acl_text_w(struct archive *, struct archive_acl *, int);
int archive_acl_text_l(struct archive_acl *, int, const char **, size_t *,
struct archive_string_conv *);
/*
* Private ACL parser. This is private because it handles some
* very weird formats that clients should not be messing with.
* Clients should only deal with their platform-native formats.
* Because of the need to support many formats cleanly, new arguments
* are likely to get added on a regular basis. Clients who try to use
* this interface are likely to be surprised when it changes.
*/
int archive_acl_parse_w(struct archive_acl *,
const wchar_t *, int /* type */);
int archive_acl_parse_l(struct archive_acl *,
const char *, int /* type */,
struct archive_string_conv *);
#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */

View file

@ -0,0 +1,175 @@
/*-
* Copyright (c) 2003-2010 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD: head/lib/libarchive/archive_check_magic.c 201089 2009-12-28 02:20:23Z kientzle $");
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#if defined(_WIN32) && !defined(__CYGWIN__)
#include <windows.h>
#include <winbase.h>
#endif
#include "archive_private.h"
static void
errmsg(const char *m)
{
size_t s = strlen(m);
ssize_t written;
while (s > 0) {
written = write(2, m, strlen(m));
if (written <= 0)
return;
m += written;
s -= written;
}
}
static void
diediedie(void)
{
#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
/* Cause a breakpoint exception */
DebugBreak();
#endif
abort(); /* Terminate the program abnormally. */
}
static const char *
state_name(unsigned s)
{
switch (s) {
case ARCHIVE_STATE_NEW: return ("new");
case ARCHIVE_STATE_HEADER: return ("header");
case ARCHIVE_STATE_DATA: return ("data");
case ARCHIVE_STATE_EOF: return ("eof");
case ARCHIVE_STATE_CLOSED: return ("closed");
case ARCHIVE_STATE_FATAL: return ("fatal");
default: return ("??");
}
}
static const char *
archive_handle_type_name(unsigned m)
{
switch (m) {
case ARCHIVE_WRITE_MAGIC: return ("archive_write");
case ARCHIVE_READ_MAGIC: return ("archive_read");
case ARCHIVE_WRITE_DISK_MAGIC: return ("archive_write_disk");
case ARCHIVE_READ_DISK_MAGIC: return ("archive_read_disk");
case ARCHIVE_MATCH_MAGIC: return ("archive_match");
default: return NULL;
}
}
static char *
write_all_states(char *buff, unsigned int states)
{
unsigned int lowbit;
buff[0] = '\0';
/* A trick for computing the lowest set bit. */
while ((lowbit = states & (1 + ~states)) != 0) {
states &= ~lowbit; /* Clear the low bit. */
strcat(buff, state_name(lowbit));
if (states != 0)
strcat(buff, "/");
}
return buff;
}
/*
* Check magic value and current state.
* Magic value mismatches are fatal and result in calls to abort().
* State mismatches return ARCHIVE_FATAL.
* Otherwise, returns ARCHIVE_OK.
*
* This is designed to catch serious programming errors that violate
* the libarchive API.
*/
int
__archive_check_magic(struct archive *a, unsigned int magic,
unsigned int state, const char *function)
{
char states1[64];
char states2[64];
const char *handle_type;
/*
* If this isn't some form of archive handle,
* then the library user has screwed up so bad that
* we don't even have a reliable way to report an error.
*/
handle_type = archive_handle_type_name(a->magic);
if (!handle_type) {
errmsg("PROGRAMMER ERROR: Function ");
errmsg(function);
errmsg(" invoked with invalid archive handle.\n");
diediedie();
}
if (a->magic != magic) {
archive_set_error(a, -1,
"PROGRAMMER ERROR: Function '%s' invoked"
" on '%s' archive object, which is not supported.",
function,
handle_type);
a->state = ARCHIVE_STATE_FATAL;
return (ARCHIVE_FATAL);
}
if ((a->state & state) == 0) {
/* If we're already FATAL, don't overwrite the error. */
if (a->state != ARCHIVE_STATE_FATAL)
archive_set_error(a, -1,
"INTERNAL ERROR: Function '%s' invoked with"
" archive structure in state '%s',"
" should be in state '%s'",
function,
write_all_states(states1, a->state),
write_all_states(states2, state));
a->state = ARCHIVE_STATE_FATAL;
return (ARCHIVE_FATAL);
}
return ARCHIVE_OK;
}

View file

@ -0,0 +1,227 @@
/*-
* Copyright (c) 2012 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD$");
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
#include "archive.h"
#include "archive_cmdline_private.h"
#include "archive_string.h"
static int cmdline_set_path(struct archive_cmdline *, const char *);
static int cmdline_add_arg(struct archive_cmdline *, const char *);
static ssize_t
extract_quotation(struct archive_string *as, const char *p)
{
const char *s;
for (s = p + 1; *s;) {
if (*s == '\\') {
if (s[1] != '\0') {
archive_strappend_char(as, s[1]);
s += 2;
} else
s++;
} else if (*s == '"')
break;
else {
archive_strappend_char(as, s[0]);
s++;
}
}
if (*s != '"')
return (ARCHIVE_FAILED);/* Invalid sequence. */
return ((ssize_t)(s + 1 - p));
}
static ssize_t
get_argument(struct archive_string *as, const char *p)
{
const char *s = p;
archive_string_empty(as);
/* Skip beginning space characters. */
while (*s != '\0' && *s == ' ')
s++;
/* Copy non-space characters. */
while (*s != '\0' && *s != ' ') {
if (*s == '\\') {
if (s[1] != '\0') {
archive_strappend_char(as, s[1]);
s += 2;
} else {
s++;/* Ignore this character.*/
break;
}
} else if (*s == '"') {
ssize_t q = extract_quotation(as, s);
if (q < 0)
return (ARCHIVE_FAILED);/* Invalid sequence. */
s += q;
} else {
archive_strappend_char(as, s[0]);
s++;
}
}
return ((ssize_t)(s - p));
}
/*
* Set up command line arguments.
* Returns ARChIVE_OK if everything okey.
* Returns ARChIVE_FAILED if there is a lack of the `"' terminator or an
* empty command line.
* Returns ARChIVE_FATAL if no memory.
*/
int
__archive_cmdline_parse(struct archive_cmdline *data, const char *cmd)
{
struct archive_string as;
const char *p;
ssize_t al;
int r;
archive_string_init(&as);
/* Get first argument as a command path. */
al = get_argument(&as, cmd);
if (al < 0) {
r = ARCHIVE_FAILED;/* Invalid sequence. */
goto exit_function;
}
if (archive_strlen(&as) == 0) {
r = ARCHIVE_FAILED;/* An empty command path. */
goto exit_function;
}
r = cmdline_set_path(data, as.s);
if (r != ARCHIVE_OK)
goto exit_function;
p = strrchr(as.s, '/');
if (p == NULL)
p = as.s;
else
p++;
r = cmdline_add_arg(data, p);
if (r != ARCHIVE_OK)
goto exit_function;
cmd += al;
for (;;) {
al = get_argument(&as, cmd);
if (al < 0) {
r = ARCHIVE_FAILED;/* Invalid sequence. */
goto exit_function;
}
if (al == 0)
break;
cmd += al;
if (archive_strlen(&as) == 0 && *cmd == '\0')
break;
r = cmdline_add_arg(data, as.s);
if (r != ARCHIVE_OK)
goto exit_function;
}
r = ARCHIVE_OK;
exit_function:
archive_string_free(&as);
return (r);
}
/*
* Set the program path.
*/
static int
cmdline_set_path(struct archive_cmdline *data, const char *path)
{
char *newptr;
newptr = realloc(data->path, strlen(path) + 1);
if (newptr == NULL)
return (ARCHIVE_FATAL);
data->path = newptr;
strcpy(data->path, path);
return (ARCHIVE_OK);
}
/*
* Add a argument for the program.
*/
static int
cmdline_add_arg(struct archive_cmdline *data, const char *arg)
{
char **newargv;
if (data->path == NULL)
return (ARCHIVE_FAILED);
newargv = realloc(data->argv, (data->argc + 2) * sizeof(char *));
if (newargv == NULL)
return (ARCHIVE_FATAL);
data->argv = newargv;
data->argv[data->argc] = strdup(arg);
if (data->argv[data->argc] == NULL)
return (ARCHIVE_FATAL);
/* Set the terminator of argv. */
data->argv[++data->argc] = NULL;
return (ARCHIVE_OK);
}
struct archive_cmdline *
__archive_cmdline_allocate(void)
{
return (struct archive_cmdline *)
calloc(1, sizeof(struct archive_cmdline));
}
/*
* Release the resources.
*/
int
__archive_cmdline_free(struct archive_cmdline *data)
{
if (data) {
free(data->path);
if (data->argv != NULL) {
int i;
for (i = 0; data->argv[i] != NULL; i++)
free(data->argv[i]);
free(data->argv);
}
free(data);
}
return (ARCHIVE_OK);
}

View file

@ -0,0 +1,47 @@
/*-
* Copyright (c) 2012 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef __LIBARCHIVE_BUILD
#ifndef __LIBARCHIVE_TEST
#error This header is only to be used internally to libarchive.
#endif
#endif
#ifndef ARCHIVE_CMDLINE_PRIVATE_H
#define ARCHIVE_CMDLINE_PRIVATE_H
struct archive_cmdline {
char *path;
char **argv;
int argc;
};
struct archive_cmdline *__archive_cmdline_allocate(void);
int __archive_cmdline_parse(struct archive_cmdline *, const char *);
int __archive_cmdline_free(struct archive_cmdline *);
#endif

View file

@ -0,0 +1,78 @@
/*-
* Copyright (c) 2009 Joerg Sonnenberger
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: head/lib/libarchive/archive_crc32.h 201102 2009-12-28 03:11:36Z kientzle $
*/
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
/*
* When zlib is unavailable, we should still be able to validate
* uncompressed zip archives. That requires us to be able to compute
* the CRC32 check value. This is a drop-in compatible replacement
* for crc32() from zlib. It's slower than the zlib implementation,
* but still pretty fast: This runs about 300MB/s on my 3GHz P4
* compared to about 800MB/s for the zlib implementation.
*/
static unsigned long
crc32(unsigned long crc, const void *_p, size_t len)
{
unsigned long crc2, b, i;
const unsigned char *p = _p;
static volatile int crc_tbl_inited = 0;
static unsigned long crc_tbl[256];
if (!crc_tbl_inited) {
for (b = 0; b < 256; ++b) {
crc2 = b;
for (i = 8; i > 0; --i) {
if (crc2 & 1)
crc2 = (crc2 >> 1) ^ 0xedb88320UL;
else
crc2 = (crc2 >> 1);
}
crc_tbl[b] = crc2;
}
crc_tbl_inited = 1;
}
crc = crc ^ 0xffffffffUL;
/* A use of this loop is about 20% - 30% faster than
* no use version in any optimization option of gcc. */
for (;len >= 8; len -= 8) {
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
}
while (len--)
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
return (crc ^ 0xffffffffUL);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,376 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* Copyright (c) 2011 Andres Mejia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_CRYPTO_PRIVATE_H_INCLUDED
#define ARCHIVE_CRYPTO_PRIVATE_H_INCLUDED
/*
* Crypto support in various Operating Systems:
*
* NetBSD:
* - MD5 and SHA1 in libc: without _ after algorithm name
* - SHA2 in libc: with _ after algorithm name
*
* OpenBSD:
* - MD5, SHA1 and SHA2 in libc: without _ after algorithm name
* - OpenBSD 4.4 and earlier have SHA2 in libc with _ after algorithm name
*
* DragonFly and FreeBSD:
* - MD5 libmd: without _ after algorithm name
* - SHA1, SHA256 and SHA512 in libmd: with _ after algorithm name
*
* Mac OS X (10.4 and later):
* - MD5, SHA1 and SHA2 in libSystem: with CC_ prefix and _ after algorithm name
*
* OpenSSL:
* - MD5, SHA1 and SHA2 in libcrypto: with _ after algorithm name
*
* Windows:
* - MD5, SHA1 and SHA2 in archive_crypto.c using Windows crypto API
*/
/* libc crypto headers */
#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
#include <md5.h>
#endif
#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
#include <rmd160.h>
#endif
#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
#include <sha1.h>
#endif
#if defined(ARCHIVE_CRYPTO_SHA256_LIBC) ||\
defined(ARCHIVE_CRYPTO_SHA256_LIBC2) ||\
defined(ARCHIVE_CRYPTO_SHA256_LIBC3) ||\
defined(ARCHIVE_CRYPTO_SHA384_LIBC) ||\
defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\
defined(ARCHIVE_CRYPTO_SHA384_LIBC3) ||\
defined(ARCHIVE_CRYPTO_SHA512_LIBC) ||\
defined(ARCHIVE_CRYPTO_SHA512_LIBC2) ||\
defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
#include <sha2.h>
#endif
/* libmd crypto headers */
#if defined(ARCHIVE_CRYPTO_MD5_LIBMD) ||\
defined(ARCHIVE_CRYPTO_RMD160_LIBMD) ||\
defined(ARCHIVE_CRYPTO_SHA1_LIBMD) ||\
defined(ARCHIVE_CRYPTO_SHA256_LIBMD) ||\
defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
#define ARCHIVE_CRYPTO_LIBMD 1
#endif
#if defined(ARCHIVE_CRYPTO_MD5_LIBMD)
#include <md5.h>
#endif
#if defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
#include <ripemd.h>
#endif
#if defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
#include <sha.h>
#endif
#if defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
#include <sha256.h>
#endif
#if defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
#include <sha512.h>
#endif
/* libSystem crypto headers */
#if defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) ||\
defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) ||\
defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) ||\
defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) ||\
defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
#include <CommonCrypto/CommonDigest.h>
#endif
/* Nettle crypto headers */
#if defined(ARCHIVE_CRYPTO_MD5_NETTLE)
#include <nettle/md5.h>
#endif
#if defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
#include <nettle/ripemd160.h>
#endif
#if defined(ARCHIVE_CRYPTO_SHA1_NETTLE) ||\
defined(ARCHIVE_CRYPTO_SHA256_NETTLE) ||\
defined(ARCHIVE_CRYPTO_SHA384_NETTLE) ||\
defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
#include <nettle/sha.h>
#endif
/* OpenSSL crypto headers */
#if defined(ARCHIVE_CRYPTO_MD5_OPENSSL) ||\
defined(ARCHIVE_CRYPTO_RMD160_OPENSSL) ||\
defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) ||\
defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) ||\
defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) ||\
defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
#define ARCHIVE_CRYPTO_OPENSSL 1
#include <openssl/evp.h>
#endif
/* Windows crypto headers */
#if defined(ARCHIVE_CRYPTO_MD5_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA1_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA512_WIN)
#include <wincrypt.h>
typedef struct {
int valid;
HCRYPTPROV cryptProv;
HCRYPTHASH hash;
} Digest_CTX;
#endif
/* typedefs */
#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
typedef MD5_CTX archive_md5_ctx;
#elif defined(ARCHIVE_CRYPTO_MD5_LIBMD)
typedef MD5_CTX archive_md5_ctx;
#elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM)
typedef CC_MD5_CTX archive_md5_ctx;
#elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
typedef struct md5_ctx archive_md5_ctx;
#elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL)
typedef EVP_MD_CTX archive_md5_ctx;
#elif defined(ARCHIVE_CRYPTO_MD5_WIN)
typedef Digest_CTX archive_md5_ctx;
#else
typedef unsigned char archive_md5_ctx;
#endif
#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
typedef RMD160_CTX archive_rmd160_ctx;
#elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
typedef RIPEMD160_CTX archive_rmd160_ctx;
#elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
typedef struct ripemd160_ctx archive_rmd160_ctx;
#elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
typedef EVP_MD_CTX archive_rmd160_ctx;
#else
typedef unsigned char archive_rmd160_ctx;
#endif
#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
typedef SHA1_CTX archive_sha1_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
typedef SHA1_CTX archive_sha1_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM)
typedef CC_SHA1_CTX archive_sha1_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
typedef struct sha1_ctx archive_sha1_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL)
typedef EVP_MD_CTX archive_sha1_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA1_WIN)
typedef Digest_CTX archive_sha1_ctx;
#else
typedef unsigned char archive_sha1_ctx;
#endif
#if defined(ARCHIVE_CRYPTO_SHA256_LIBC)
typedef SHA256_CTX archive_sha256_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC2)
typedef SHA256_CTX archive_sha256_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC3)
typedef SHA2_CTX archive_sha256_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
typedef SHA256_CTX archive_sha256_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM)
typedef CC_SHA256_CTX archive_sha256_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
typedef struct sha256_ctx archive_sha256_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL)
typedef EVP_MD_CTX archive_sha256_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA256_WIN)
typedef Digest_CTX archive_sha256_ctx;
#else
typedef unsigned char archive_sha256_ctx;
#endif
#if defined(ARCHIVE_CRYPTO_SHA384_LIBC)
typedef SHA384_CTX archive_sha384_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC2)
typedef SHA384_CTX archive_sha384_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC3)
typedef SHA2_CTX archive_sha384_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM)
typedef CC_SHA512_CTX archive_sha384_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
typedef struct sha384_ctx archive_sha384_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL)
typedef EVP_MD_CTX archive_sha384_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA384_WIN)
typedef Digest_CTX archive_sha384_ctx;
#else
typedef unsigned char archive_sha384_ctx;
#endif
#if defined(ARCHIVE_CRYPTO_SHA512_LIBC)
typedef SHA512_CTX archive_sha512_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC2)
typedef SHA512_CTX archive_sha512_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
typedef SHA2_CTX archive_sha512_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
typedef SHA512_CTX archive_sha512_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
typedef CC_SHA512_CTX archive_sha512_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
typedef struct sha512_ctx archive_sha512_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
typedef EVP_MD_CTX archive_sha512_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA512_WIN)
typedef Digest_CTX archive_sha512_ctx;
#else
typedef unsigned char archive_sha512_ctx;
#endif
/* defines */
#if defined(ARCHIVE_CRYPTO_MD5_LIBC) ||\
defined(ARCHIVE_CRYPTO_MD5_LIBMD) || \
defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) ||\
defined(ARCHIVE_CRYPTO_MD5_NETTLE) ||\
defined(ARCHIVE_CRYPTO_MD5_OPENSSL) ||\
defined(ARCHIVE_CRYPTO_MD5_WIN)
#define ARCHIVE_HAS_MD5
#endif
#define archive_md5_init(ctx)\
__archive_crypto.md5init(ctx)
#define archive_md5_final(ctx, md)\
__archive_crypto.md5final(ctx, md)
#define archive_md5_update(ctx, buf, n)\
__archive_crypto.md5update(ctx, buf, n)
#if defined(ARCHIVE_CRYPTO_RMD160_LIBC) ||\
defined(ARCHIVE_CRYPTO_RMD160_NETTLE) ||\
defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
#define ARCHIVE_HAS_RMD160
#endif
#define archive_rmd160_init(ctx)\
__archive_crypto.rmd160init(ctx)
#define archive_rmd160_final(ctx, md)\
__archive_crypto.rmd160final(ctx, md)
#define archive_rmd160_update(ctx, buf, n)\
__archive_crypto.rmd160update(ctx, buf, n)
#if defined(ARCHIVE_CRYPTO_SHA1_LIBC) ||\
defined(ARCHIVE_CRYPTO_SHA1_LIBMD) || \
defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) ||\
defined(ARCHIVE_CRYPTO_SHA1_NETTLE) ||\
defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) ||\
defined(ARCHIVE_CRYPTO_SHA1_WIN)
#define ARCHIVE_HAS_SHA1
#endif
#define archive_sha1_init(ctx)\
__archive_crypto.sha1init(ctx)
#define archive_sha1_final(ctx, md)\
__archive_crypto.sha1final(ctx, md)
#define archive_sha1_update(ctx, buf, n)\
__archive_crypto.sha1update(ctx, buf, n)
#if defined(ARCHIVE_CRYPTO_SHA256_LIBC) ||\
defined(ARCHIVE_CRYPTO_SHA256_LIBC2) ||\
defined(ARCHIVE_CRYPTO_SHA256_LIBC3) ||\
defined(ARCHIVE_CRYPTO_SHA256_LIBMD) ||\
defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) ||\
defined(ARCHIVE_CRYPTO_SHA256_NETTLE) ||\
defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) ||\
defined(ARCHIVE_CRYPTO_SHA256_WIN)
#define ARCHIVE_HAS_SHA256
#endif
#define archive_sha256_init(ctx)\
__archive_crypto.sha256init(ctx)
#define archive_sha256_final(ctx, md)\
__archive_crypto.sha256final(ctx, md)
#define archive_sha256_update(ctx, buf, n)\
__archive_crypto.sha256update(ctx, buf, n)
#if defined(ARCHIVE_CRYPTO_SHA384_LIBC) ||\
defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\
defined(ARCHIVE_CRYPTO_SHA384_LIBC3) ||\
defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) ||\
defined(ARCHIVE_CRYPTO_SHA384_NETTLE) ||\
defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) ||\
defined(ARCHIVE_CRYPTO_SHA384_WIN)
#define ARCHIVE_HAS_SHA384
#endif
#define archive_sha384_init(ctx)\
__archive_crypto.sha384init(ctx)
#define archive_sha384_final(ctx, md)\
__archive_crypto.sha384final(ctx, md)
#define archive_sha384_update(ctx, buf, n)\
__archive_crypto.sha384update(ctx, buf, n)
#if defined(ARCHIVE_CRYPTO_SHA512_LIBC) ||\
defined(ARCHIVE_CRYPTO_SHA512_LIBC2) ||\
defined(ARCHIVE_CRYPTO_SHA512_LIBC3) ||\
defined(ARCHIVE_CRYPTO_SHA512_LIBMD) ||\
defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM) ||\
defined(ARCHIVE_CRYPTO_SHA512_NETTLE) ||\
defined(ARCHIVE_CRYPTO_SHA512_OPENSSL) ||\
defined(ARCHIVE_CRYPTO_SHA512_WIN)
#define ARCHIVE_HAS_SHA512
#endif
#define archive_sha512_init(ctx)\
__archive_crypto.sha512init(ctx)
#define archive_sha512_final(ctx, md)\
__archive_crypto.sha512final(ctx, md)
#define archive_sha512_update(ctx, buf, n)\
__archive_crypto.sha512update(ctx, buf, n)
/* Minimal interface to crypto functionality for internal use in libarchive */
struct archive_crypto
{
/* Message Digest */
int (*md5init)(archive_md5_ctx *ctx);
int (*md5update)(archive_md5_ctx *, const void *, size_t);
int (*md5final)(archive_md5_ctx *, void *);
int (*rmd160init)(archive_rmd160_ctx *);
int (*rmd160update)(archive_rmd160_ctx *, const void *, size_t);
int (*rmd160final)(archive_rmd160_ctx *, void *);
int (*sha1init)(archive_sha1_ctx *);
int (*sha1update)(archive_sha1_ctx *, const void *, size_t);
int (*sha1final)(archive_sha1_ctx *, void *);
int (*sha256init)(archive_sha256_ctx *);
int (*sha256update)(archive_sha256_ctx *, const void *, size_t);
int (*sha256final)(archive_sha256_ctx *, void *);
int (*sha384init)(archive_sha384_ctx *);
int (*sha384update)(archive_sha384_ctx *, const void *, size_t);
int (*sha384final)(archive_sha384_ctx *, void *);
int (*sha512init)(archive_sha512_ctx *);
int (*sha512update)(archive_sha512_ctx *, const void *, size_t);
int (*sha512final)(archive_sha512_ctx *, void *);
};
extern const struct archive_crypto __archive_crypto;
#endif

View file

@ -0,0 +1,162 @@
/*-
* Copyright (c) 2002 Thomas Moestl <tmm@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: head/lib/libarchive/archive_endian.h 201085 2009-12-28 02:17:15Z kientzle $
*
* Borrowed from FreeBSD's <sys/endian.h>
*/
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
/* Note: This is a purely internal header! */
/* Do not use this outside of libarchive internal code! */
#ifndef ARCHIVE_ENDIAN_H_INCLUDED
#define ARCHIVE_ENDIAN_H_INCLUDED
/*
* Disabling inline keyword for compilers known to choke on it:
* - Watcom C++ in C code. (For any version?)
* - SGI MIPSpro
* - Microsoft Visual C++ 6.0 (supposedly newer versions too)
*/
#if defined(__WATCOMC__) || defined(__sgi) || defined(__hpux) || defined(__BORLANDC__)
#define inline
#elif defined(_MSC_VER)
#define inline __inline
#endif
/* Alignment-agnostic encode/decode bytestream to/from little/big endian. */
static inline uint16_t
archive_be16dec(const void *pp)
{
unsigned char const *p = (unsigned char const *)pp;
return ((p[0] << 8) | p[1]);
}
static inline uint32_t
archive_be32dec(const void *pp)
{
unsigned char const *p = (unsigned char const *)pp;
return ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
}
static inline uint64_t
archive_be64dec(const void *pp)
{
unsigned char const *p = (unsigned char const *)pp;
return (((uint64_t)archive_be32dec(p) << 32) | archive_be32dec(p + 4));
}
static inline uint16_t
archive_le16dec(const void *pp)
{
unsigned char const *p = (unsigned char const *)pp;
return ((p[1] << 8) | p[0]);
}
static inline uint32_t
archive_le32dec(const void *pp)
{
unsigned char const *p = (unsigned char const *)pp;
return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
}
static inline uint64_t
archive_le64dec(const void *pp)
{
unsigned char const *p = (unsigned char const *)pp;
return (((uint64_t)archive_le32dec(p + 4) << 32) | archive_le32dec(p));
}
static inline void
archive_be16enc(void *pp, uint16_t u)
{
unsigned char *p = (unsigned char *)pp;
p[0] = (u >> 8) & 0xff;
p[1] = u & 0xff;
}
static inline void
archive_be32enc(void *pp, uint32_t u)
{
unsigned char *p = (unsigned char *)pp;
p[0] = (u >> 24) & 0xff;
p[1] = (u >> 16) & 0xff;
p[2] = (u >> 8) & 0xff;
p[3] = u & 0xff;
}
static inline void
archive_be64enc(void *pp, uint64_t u)
{
unsigned char *p = (unsigned char *)pp;
archive_be32enc(p, (uint32_t)(u >> 32));
archive_be32enc(p + 4, (uint32_t)(u & 0xffffffff));
}
static inline void
archive_le16enc(void *pp, uint16_t u)
{
unsigned char *p = (unsigned char *)pp;
p[0] = u & 0xff;
p[1] = (u >> 8) & 0xff;
}
static inline void
archive_le32enc(void *pp, uint32_t u)
{
unsigned char *p = (unsigned char *)pp;
p[0] = u & 0xff;
p[1] = (u >> 8) & 0xff;
p[2] = (u >> 16) & 0xff;
p[3] = (u >> 24) & 0xff;
}
static inline void
archive_le64enc(void *pp, uint64_t u)
{
unsigned char *p = (unsigned char *)pp;
archive_le32enc(p, (uint32_t)(u & 0xffffffff));
archive_le32enc(p + 4, (uint32_t)(u >> 32));
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,615 @@
/*-
* Copyright (c) 2003-2008 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: head/lib/libarchive/archive_entry.h 201096 2009-12-28 02:41:27Z kientzle $
*/
#ifndef ARCHIVE_ENTRY_H_INCLUDED
#define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */
#define ARCHIVE_VERSION_NUMBER 3001002
/*
* Note: archive_entry.h is for use outside of libarchive; the
* configuration headers (config.h, archive_platform.h, etc.) are
* purely internal. Do NOT use HAVE_XXX configuration macros to
* control the behavior of this header! If you must conditionalize,
* use predefined compiler and/or platform macros.
*/
#include <sys/types.h>
#include <stddef.h> /* for wchar_t */
#include <time.h>
#if defined(_WIN32) && !defined(__CYGWIN__)
#include <windows.h>
#endif
/* Get a suitable 64-bit integer type. */
#if defined(_WIN32) && !defined(__CYGWIN__)
# define __LA_INT64_T __int64
#else
#include <unistd.h>
# if defined(_SCO_DS)
# define __LA_INT64_T long long
# else
# define __LA_INT64_T int64_t
# endif
#endif
/* Get a suitable definition for mode_t */
#if ARCHIVE_VERSION_NUMBER >= 3999000
/* Switch to plain 'int' for libarchive 4.0. It's less broken than 'mode_t' */
# define __LA_MODE_T int
#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__)
# define __LA_MODE_T unsigned short
#else
# define __LA_MODE_T mode_t
#endif
/*
* On Windows, define LIBARCHIVE_STATIC if you're building or using a
* .lib. The default here assumes you're building a DLL. Only
* libarchive source should ever define __LIBARCHIVE_BUILD.
*/
#if ((defined __WIN32__) || (defined _WIN32) || defined(__CYGWIN__)) && (!defined LIBARCHIVE_STATIC)
# ifdef __LIBARCHIVE_BUILD
# ifdef __GNUC__
# define __LA_DECL __attribute__((dllexport)) extern
# else
# define __LA_DECL __declspec(dllexport)
# endif
# else
# ifdef __GNUC__
# define __LA_DECL
# else
# define __LA_DECL __declspec(dllimport)
# endif
# endif
#else
/* Static libraries on all platforms and shared libraries on non-Windows. */
# define __LA_DECL
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* Description of an archive entry.
*
* You can think of this as "struct stat" with some text fields added in.
*
* TODO: Add "comment", "charset", and possibly other entries that are
* supported by "pax interchange" format. However, GNU, ustar, cpio,
* and other variants don't support these features, so they're not an
* excruciatingly high priority right now.
*
* TODO: "pax interchange" format allows essentially arbitrary
* key/value attributes to be attached to any entry. Supporting
* such extensions may make this library useful for special
* applications (e.g., a package manager could attach special
* package-management attributes to each entry).
*/
struct archive;
struct archive_entry;
/*
* File-type constants. These are returned from archive_entry_filetype()
* and passed to archive_entry_set_filetype().
*
* These values match S_XXX defines on every platform I've checked,
* including Windows, AIX, Linux, Solaris, and BSD. They're
* (re)defined here because platforms generally don't define the ones
* they don't support. For example, Windows doesn't define S_IFLNK or
* S_IFBLK. Instead of having a mass of conditional logic and system
* checks to define any S_XXX values that aren't supported locally,
* I've just defined a new set of such constants so that
* libarchive-based applications can manipulate and identify archive
* entries properly even if the hosting platform can't store them on
* disk.
*
* These values are also used directly within some portable formats,
* such as cpio. If you find a platform that varies from these, the
* correct solution is to leave these alone and translate from these
* portable values to platform-native values when entries are read from
* or written to disk.
*/
/*
* In libarchive 4.0, we can drop the casts here.
* They're needed to work around Borland C's broken mode_t.
*/
#define AE_IFMT ((__LA_MODE_T)0170000)
#define AE_IFREG ((__LA_MODE_T)0100000)
#define AE_IFLNK ((__LA_MODE_T)0120000)
#define AE_IFSOCK ((__LA_MODE_T)0140000)
#define AE_IFCHR ((__LA_MODE_T)0020000)
#define AE_IFBLK ((__LA_MODE_T)0060000)
#define AE_IFDIR ((__LA_MODE_T)0040000)
#define AE_IFIFO ((__LA_MODE_T)0010000)
/*
* Basic object manipulation
*/
__LA_DECL struct archive_entry *archive_entry_clear(struct archive_entry *);
/* The 'clone' function does a deep copy; all of the strings are copied too. */
__LA_DECL struct archive_entry *archive_entry_clone(struct archive_entry *);
__LA_DECL void archive_entry_free(struct archive_entry *);
__LA_DECL struct archive_entry *archive_entry_new(void);
/*
* This form of archive_entry_new2() will pull character-set
* conversion information from the specified archive handle. The
* older archive_entry_new(void) form is equivalent to calling
* archive_entry_new2(NULL) and will result in the use of an internal
* default character-set conversion.
*/
__LA_DECL struct archive_entry *archive_entry_new2(struct archive *);
/*
* Retrieve fields from an archive_entry.
*
* There are a number of implicit conversions among these fields. For
* example, if a regular string field is set and you read the _w wide
* character field, the entry will implicitly convert narrow-to-wide
* using the current locale. Similarly, dev values are automatically
* updated when you write devmajor or devminor and vice versa.
*
* In addition, fields can be "set" or "unset." Unset string fields
* return NULL, non-string fields have _is_set() functions to test
* whether they've been set. You can "unset" a string field by
* assigning NULL; non-string fields have _unset() functions to
* unset them.
*
* Note: There is one ambiguity in the above; string fields will
* also return NULL when implicit character set conversions fail.
* This is usually what you want.
*/
__LA_DECL time_t archive_entry_atime(struct archive_entry *);
__LA_DECL long archive_entry_atime_nsec(struct archive_entry *);
__LA_DECL int archive_entry_atime_is_set(struct archive_entry *);
__LA_DECL time_t archive_entry_birthtime(struct archive_entry *);
__LA_DECL long archive_entry_birthtime_nsec(struct archive_entry *);
__LA_DECL int archive_entry_birthtime_is_set(struct archive_entry *);
__LA_DECL time_t archive_entry_ctime(struct archive_entry *);
__LA_DECL long archive_entry_ctime_nsec(struct archive_entry *);
__LA_DECL int archive_entry_ctime_is_set(struct archive_entry *);
__LA_DECL dev_t archive_entry_dev(struct archive_entry *);
__LA_DECL int archive_entry_dev_is_set(struct archive_entry *);
__LA_DECL dev_t archive_entry_devmajor(struct archive_entry *);
__LA_DECL dev_t archive_entry_devminor(struct archive_entry *);
__LA_DECL __LA_MODE_T archive_entry_filetype(struct archive_entry *);
__LA_DECL void archive_entry_fflags(struct archive_entry *,
unsigned long * /* set */,
unsigned long * /* clear */);
__LA_DECL const char *archive_entry_fflags_text(struct archive_entry *);
__LA_DECL __LA_INT64_T archive_entry_gid(struct archive_entry *);
__LA_DECL const char *archive_entry_gname(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_gname_w(struct archive_entry *);
__LA_DECL const char *archive_entry_hardlink(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_hardlink_w(struct archive_entry *);
__LA_DECL __LA_INT64_T archive_entry_ino(struct archive_entry *);
__LA_DECL __LA_INT64_T archive_entry_ino64(struct archive_entry *);
__LA_DECL int archive_entry_ino_is_set(struct archive_entry *);
__LA_DECL __LA_MODE_T archive_entry_mode(struct archive_entry *);
__LA_DECL time_t archive_entry_mtime(struct archive_entry *);
__LA_DECL long archive_entry_mtime_nsec(struct archive_entry *);
__LA_DECL int archive_entry_mtime_is_set(struct archive_entry *);
__LA_DECL unsigned int archive_entry_nlink(struct archive_entry *);
__LA_DECL const char *archive_entry_pathname(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_pathname_w(struct archive_entry *);
__LA_DECL __LA_MODE_T archive_entry_perm(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdev(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdevmajor(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdevminor(struct archive_entry *);
__LA_DECL const char *archive_entry_sourcepath(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_sourcepath_w(struct archive_entry *);
__LA_DECL __LA_INT64_T archive_entry_size(struct archive_entry *);
__LA_DECL int archive_entry_size_is_set(struct archive_entry *);
__LA_DECL const char *archive_entry_strmode(struct archive_entry *);
__LA_DECL const char *archive_entry_symlink(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_symlink_w(struct archive_entry *);
__LA_DECL __LA_INT64_T archive_entry_uid(struct archive_entry *);
__LA_DECL const char *archive_entry_uname(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_uname_w(struct archive_entry *);
/*
* Set fields in an archive_entry.
*
* Note: Before libarchive 2.4, there were 'set' and 'copy' versions
* of the string setters. 'copy' copied the actual string, 'set' just
* stored the pointer. In libarchive 2.4 and later, strings are
* always copied.
*/
__LA_DECL void archive_entry_set_atime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_unset_atime(struct archive_entry *);
#if defined(_WIN32) && !defined(__CYGWIN__)
__LA_DECL void archive_entry_copy_bhfi(struct archive_entry *, BY_HANDLE_FILE_INFORMATION *);
#endif
__LA_DECL void archive_entry_set_birthtime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_unset_birthtime(struct archive_entry *);
__LA_DECL void archive_entry_set_ctime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_unset_ctime(struct archive_entry *);
__LA_DECL void archive_entry_set_dev(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_devmajor(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_devminor(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_filetype(struct archive_entry *, unsigned int);
__LA_DECL void archive_entry_set_fflags(struct archive_entry *,
unsigned long /* set */, unsigned long /* clear */);
/* Returns pointer to start of first invalid token, or NULL if none. */
/* Note that all recognized tokens are processed, regardless. */
__LA_DECL const char *archive_entry_copy_fflags_text(struct archive_entry *,
const char *);
__LA_DECL const wchar_t *archive_entry_copy_fflags_text_w(struct archive_entry *,
const wchar_t *);
__LA_DECL void archive_entry_set_gid(struct archive_entry *, __LA_INT64_T);
__LA_DECL void archive_entry_set_gname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_gname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_gname_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_gname_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_hardlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_hardlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_hardlink_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_hardlink_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_ino(struct archive_entry *, __LA_INT64_T);
__LA_DECL void archive_entry_set_ino64(struct archive_entry *, __LA_INT64_T);
__LA_DECL void archive_entry_set_link(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_link(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_link_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_link_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_mode(struct archive_entry *, __LA_MODE_T);
__LA_DECL void archive_entry_set_mtime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_unset_mtime(struct archive_entry *);
__LA_DECL void archive_entry_set_nlink(struct archive_entry *, unsigned int);
__LA_DECL void archive_entry_set_pathname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_pathname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_pathname_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_pathname_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_perm(struct archive_entry *, __LA_MODE_T);
__LA_DECL void archive_entry_set_rdev(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_rdevmajor(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_rdevminor(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_size(struct archive_entry *, __LA_INT64_T);
__LA_DECL void archive_entry_unset_size(struct archive_entry *);
__LA_DECL void archive_entry_copy_sourcepath(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_sourcepath_w(struct archive_entry *, const wchar_t *);
__LA_DECL void archive_entry_set_symlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_symlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_symlink_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_uid(struct archive_entry *, __LA_INT64_T);
__LA_DECL void archive_entry_set_uname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_uname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_uname_utf8(struct archive_entry *, const char *);
/*
* Routines to bulk copy fields to/from a platform-native "struct
* stat." Libarchive used to just store a struct stat inside of each
* archive_entry object, but this created issues when trying to
* manipulate archives on systems different than the ones they were
* created on.
*
* TODO: On Linux and other LFS systems, provide both stat32 and
* stat64 versions of these functions and all of the macro glue so
* that archive_entry_stat is magically defined to
* archive_entry_stat32 or archive_entry_stat64 as appropriate.
*/
__LA_DECL const struct stat *archive_entry_stat(struct archive_entry *);
__LA_DECL void archive_entry_copy_stat(struct archive_entry *, const struct stat *);
/*
* Storage for Mac OS-specific AppleDouble metadata information.
* Apple-format tar files store a separate binary blob containing
* encoded metadata with ACL, extended attributes, etc.
* This provides a place to store that blob.
*/
__LA_DECL const void * archive_entry_mac_metadata(struct archive_entry *, size_t *);
__LA_DECL void archive_entry_copy_mac_metadata(struct archive_entry *, const void *, size_t);
/*
* ACL routines. This used to simply store and return text-format ACL
* strings, but that proved insufficient for a number of reasons:
* = clients need control over uname/uid and gname/gid mappings
* = there are many different ACL text formats
* = would like to be able to read/convert archives containing ACLs
* on platforms that lack ACL libraries
*
* This last point, in particular, forces me to implement a reasonably
* complete set of ACL support routines.
*/
/*
* Permission bits.
*/
#define ARCHIVE_ENTRY_ACL_EXECUTE 0x00000001
#define ARCHIVE_ENTRY_ACL_WRITE 0x00000002
#define ARCHIVE_ENTRY_ACL_READ 0x00000004
#define ARCHIVE_ENTRY_ACL_READ_DATA 0x00000008
#define ARCHIVE_ENTRY_ACL_LIST_DIRECTORY 0x00000008
#define ARCHIVE_ENTRY_ACL_WRITE_DATA 0x00000010
#define ARCHIVE_ENTRY_ACL_ADD_FILE 0x00000010
#define ARCHIVE_ENTRY_ACL_APPEND_DATA 0x00000020
#define ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY 0x00000020
#define ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS 0x00000040
#define ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS 0x00000080
#define ARCHIVE_ENTRY_ACL_DELETE_CHILD 0x00000100
#define ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES 0x00000200
#define ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES 0x00000400
#define ARCHIVE_ENTRY_ACL_DELETE 0x00000800
#define ARCHIVE_ENTRY_ACL_READ_ACL 0x00001000
#define ARCHIVE_ENTRY_ACL_WRITE_ACL 0x00002000
#define ARCHIVE_ENTRY_ACL_WRITE_OWNER 0x00004000
#define ARCHIVE_ENTRY_ACL_SYNCHRONIZE 0x00008000
#define ARCHIVE_ENTRY_ACL_PERMS_POSIX1E \
(ARCHIVE_ENTRY_ACL_EXECUTE \
| ARCHIVE_ENTRY_ACL_WRITE \
| ARCHIVE_ENTRY_ACL_READ)
#define ARCHIVE_ENTRY_ACL_PERMS_NFS4 \
(ARCHIVE_ENTRY_ACL_EXECUTE \
| ARCHIVE_ENTRY_ACL_READ_DATA \
| ARCHIVE_ENTRY_ACL_LIST_DIRECTORY \
| ARCHIVE_ENTRY_ACL_WRITE_DATA \
| ARCHIVE_ENTRY_ACL_ADD_FILE \
| ARCHIVE_ENTRY_ACL_APPEND_DATA \
| ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY \
| ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS \
| ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS \
| ARCHIVE_ENTRY_ACL_DELETE_CHILD \
| ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES \
| ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES \
| ARCHIVE_ENTRY_ACL_DELETE \
| ARCHIVE_ENTRY_ACL_READ_ACL \
| ARCHIVE_ENTRY_ACL_WRITE_ACL \
| ARCHIVE_ENTRY_ACL_WRITE_OWNER \
| ARCHIVE_ENTRY_ACL_SYNCHRONIZE)
/*
* Inheritance values (NFS4 ACLs only); included in permset.
*/
#define ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT 0x02000000
#define ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT 0x04000000
#define ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT 0x08000000
#define ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY 0x10000000
#define ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS 0x20000000
#define ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS 0x40000000
#define ARCHIVE_ENTRY_ACL_INHERITANCE_NFS4 \
(ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT \
| ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT \
| ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT \
| ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY \
| ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS \
| ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS)
/* We need to be able to specify combinations of these. */
#define ARCHIVE_ENTRY_ACL_TYPE_ACCESS 256 /* POSIX.1e only */
#define ARCHIVE_ENTRY_ACL_TYPE_DEFAULT 512 /* POSIX.1e only */
#define ARCHIVE_ENTRY_ACL_TYPE_ALLOW 1024 /* NFS4 only */
#define ARCHIVE_ENTRY_ACL_TYPE_DENY 2048 /* NFS4 only */
#define ARCHIVE_ENTRY_ACL_TYPE_AUDIT 4096 /* NFS4 only */
#define ARCHIVE_ENTRY_ACL_TYPE_ALARM 8192 /* NFS4 only */
#define ARCHIVE_ENTRY_ACL_TYPE_POSIX1E (ARCHIVE_ENTRY_ACL_TYPE_ACCESS \
| ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)
#define ARCHIVE_ENTRY_ACL_TYPE_NFS4 (ARCHIVE_ENTRY_ACL_TYPE_ALLOW \
| ARCHIVE_ENTRY_ACL_TYPE_DENY \
| ARCHIVE_ENTRY_ACL_TYPE_AUDIT \
| ARCHIVE_ENTRY_ACL_TYPE_ALARM)
/* Tag values mimic POSIX.1e */
#define ARCHIVE_ENTRY_ACL_USER 10001 /* Specified user. */
#define ARCHIVE_ENTRY_ACL_USER_OBJ 10002 /* User who owns the file. */
#define ARCHIVE_ENTRY_ACL_GROUP 10003 /* Specified group. */
#define ARCHIVE_ENTRY_ACL_GROUP_OBJ 10004 /* Group who owns the file. */
#define ARCHIVE_ENTRY_ACL_MASK 10005 /* Modify group access (POSIX.1e only) */
#define ARCHIVE_ENTRY_ACL_OTHER 10006 /* Public (POSIX.1e only) */
#define ARCHIVE_ENTRY_ACL_EVERYONE 10107 /* Everyone (NFS4 only) */
/*
* Set the ACL by clearing it and adding entries one at a time.
* Unlike the POSIX.1e ACL routines, you must specify the type
* (access/default) for each entry. Internally, the ACL data is just
* a soup of entries. API calls here allow you to retrieve just the
* entries of interest. This design (which goes against the spirit of
* POSIX.1e) is useful for handling archive formats that combine
* default and access information in a single ACL list.
*/
__LA_DECL void archive_entry_acl_clear(struct archive_entry *);
__LA_DECL int archive_entry_acl_add_entry(struct archive_entry *,
int /* type */, int /* permset */, int /* tag */,
int /* qual */, const char * /* name */);
__LA_DECL int archive_entry_acl_add_entry_w(struct archive_entry *,
int /* type */, int /* permset */, int /* tag */,
int /* qual */, const wchar_t * /* name */);
/*
* To retrieve the ACL, first "reset", then repeatedly ask for the
* "next" entry. The want_type parameter allows you to request only
* certain types of entries.
*/
__LA_DECL int archive_entry_acl_reset(struct archive_entry *, int /* want_type */);
__LA_DECL int archive_entry_acl_next(struct archive_entry *, int /* want_type */,
int * /* type */, int * /* permset */, int * /* tag */,
int * /* qual */, const char ** /* name */);
__LA_DECL int archive_entry_acl_next_w(struct archive_entry *, int /* want_type */,
int * /* type */, int * /* permset */, int * /* tag */,
int * /* qual */, const wchar_t ** /* name */);
/*
* Construct a text-format ACL. The flags argument is a bitmask that
* can include any of the following:
*
* ARCHIVE_ENTRY_ACL_TYPE_ACCESS - Include POSIX.1e "access" entries.
* ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - Include POSIX.1e "default" entries.
* ARCHIVE_ENTRY_ACL_TYPE_NFS4 - Include NFS4 entries.
* ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID - Include extra numeric ID field in
* each ACL entry. ('star' introduced this for POSIX.1e, this flag
* also applies to NFS4.)
* ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT - Include "default:" before each
* default ACL entry, as used in old Solaris ACLs.
*/
#define ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 1024
#define ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 2048
__LA_DECL const wchar_t *archive_entry_acl_text_w(struct archive_entry *,
int /* flags */);
__LA_DECL const char *archive_entry_acl_text(struct archive_entry *,
int /* flags */);
/* Return a count of entries matching 'want_type' */
__LA_DECL int archive_entry_acl_count(struct archive_entry *, int /* want_type */);
/* Return an opaque ACL object. */
/* There's not yet anything clients can actually do with this... */
struct archive_acl;
__LA_DECL struct archive_acl *archive_entry_acl(struct archive_entry *);
/*
* extended attributes
*/
__LA_DECL void archive_entry_xattr_clear(struct archive_entry *);
__LA_DECL void archive_entry_xattr_add_entry(struct archive_entry *,
const char * /* name */, const void * /* value */,
size_t /* size */);
/*
* To retrieve the xattr list, first "reset", then repeatedly ask for the
* "next" entry.
*/
__LA_DECL int archive_entry_xattr_count(struct archive_entry *);
__LA_DECL int archive_entry_xattr_reset(struct archive_entry *);
__LA_DECL int archive_entry_xattr_next(struct archive_entry *,
const char ** /* name */, const void ** /* value */, size_t *);
/*
* sparse
*/
__LA_DECL void archive_entry_sparse_clear(struct archive_entry *);
__LA_DECL void archive_entry_sparse_add_entry(struct archive_entry *,
__LA_INT64_T /* offset */, __LA_INT64_T /* length */);
/*
* To retrieve the xattr list, first "reset", then repeatedly ask for the
* "next" entry.
*/
__LA_DECL int archive_entry_sparse_count(struct archive_entry *);
__LA_DECL int archive_entry_sparse_reset(struct archive_entry *);
__LA_DECL int archive_entry_sparse_next(struct archive_entry *,
__LA_INT64_T * /* offset */, __LA_INT64_T * /* length */);
/*
* Utility to match up hardlinks.
*
* The 'struct archive_entry_linkresolver' is a cache of archive entries
* for files with multiple links. Here's how to use it:
* 1. Create a lookup object with archive_entry_linkresolver_new()
* 2. Tell it the archive format you're using.
* 3. Hand each archive_entry to archive_entry_linkify().
* That function will return 0, 1, or 2 entries that should
* be written.
* 4. Call archive_entry_linkify(resolver, NULL) until
* no more entries are returned.
* 5. Call archive_entry_linkresolver_free(resolver) to free resources.
*
* The entries returned have their hardlink and size fields updated
* appropriately. If an entry is passed in that does not refer to
* a file with multiple links, it is returned unchanged. The intention
* is that you should be able to simply filter all entries through
* this machine.
*
* To make things more efficient, be sure that each entry has a valid
* nlinks value. The hardlink cache uses this to track when all links
* have been found. If the nlinks value is zero, it will keep every
* name in the cache indefinitely, which can use a lot of memory.
*
* Note that archive_entry_size() is reset to zero if the file
* body should not be written to the archive. Pay attention!
*/
struct archive_entry_linkresolver;
/*
* There are three different strategies for marking hardlinks.
* The descriptions below name them after the best-known
* formats that rely on each strategy:
*
* "Old cpio" is the simplest, it always returns any entry unmodified.
* As far as I know, only cpio formats use this. Old cpio archives
* store every link with the full body; the onus is on the dearchiver
* to detect and properly link the files as they are restored.
* "tar" is also pretty simple; it caches a copy the first time it sees
* any link. Subsequent appearances are modified to be hardlink
* references to the first one without any body. Used by all tar
* formats, although the newest tar formats permit the "old cpio" strategy
* as well. This strategy is very simple for the dearchiver,
* and reasonably straightforward for the archiver.
* "new cpio" is trickier. It stores the body only with the last
* occurrence. The complication is that we might not
* see every link to a particular file in a single session, so
* there's no easy way to know when we've seen the last occurrence.
* The solution here is to queue one link until we see the next.
* At the end of the session, you can enumerate any remaining
* entries by calling archive_entry_linkify(NULL) and store those
* bodies. If you have a file with three links l1, l2, and l3,
* you'll get the following behavior if you see all three links:
* linkify(l1) => NULL (the resolver stores l1 internally)
* linkify(l2) => l1 (resolver stores l2, you write l1)
* linkify(l3) => l2, l3 (all links seen, you can write both).
* If you only see l1 and l2, you'll get this behavior:
* linkify(l1) => NULL
* linkify(l2) => l1
* linkify(NULL) => l2 (at end, you retrieve remaining links)
* As the name suggests, this strategy is used by newer cpio variants.
* It's noticeably more complex for the archiver, slightly more complex
* for the dearchiver than the tar strategy, but makes it straightforward
* to restore a file using any link by simply continuing to scan until
* you see a link that is stored with a body. In contrast, the tar
* strategy requires you to rescan the archive from the beginning to
* correctly extract an arbitrary link.
*/
__LA_DECL struct archive_entry_linkresolver *archive_entry_linkresolver_new(void);
__LA_DECL void archive_entry_linkresolver_set_strategy(
struct archive_entry_linkresolver *, int /* format_code */);
__LA_DECL void archive_entry_linkresolver_free(struct archive_entry_linkresolver *);
__LA_DECL void archive_entry_linkify(struct archive_entry_linkresolver *,
struct archive_entry **, struct archive_entry **);
__LA_DECL struct archive_entry *archive_entry_partial_links(
struct archive_entry_linkresolver *res, unsigned int *links);
#ifdef __cplusplus
}
#endif
/* This is meaningless outside of this header. */
#undef __LA_DECL
#endif /* !ARCHIVE_ENTRY_H_INCLUDED */

View file

@ -0,0 +1,75 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD$");
#include "archive_private.h"
#include "archive_entry.h"
#if defined(_WIN32) && !defined(__CYGWIN__)
#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
__inline static void
fileTimeToUtc(const FILETIME *filetime, time_t *t, long *ns)
{
ULARGE_INTEGER utc;
utc.HighPart = filetime->dwHighDateTime;
utc.LowPart = filetime->dwLowDateTime;
if (utc.QuadPart >= EPOC_TIME) {
utc.QuadPart -= EPOC_TIME;
*t = (time_t)(utc.QuadPart / 10000000); /* milli seconds base */
*ns = (long)(utc.QuadPart % 10000000) * 100;/* nano seconds base */
} else {
*t = 0;
*ns = 0;
}
}
void
archive_entry_copy_bhfi(struct archive_entry *entry,
BY_HANDLE_FILE_INFORMATION *bhfi)
{
time_t secs;
long nsecs;
fileTimeToUtc(&bhfi->ftLastAccessTime, &secs, &nsecs);
archive_entry_set_atime(entry, secs, nsecs);
fileTimeToUtc(&bhfi->ftLastWriteTime, &secs, &nsecs);
archive_entry_set_mtime(entry, secs, nsecs);
fileTimeToUtc(&bhfi->ftCreationTime, &secs, &nsecs);
archive_entry_set_birthtime(entry, secs, nsecs);
archive_entry_set_ctime(entry, secs, nsecs);
archive_entry_set_dev(entry, bhfi->dwVolumeSerialNumber);
archive_entry_set_ino64(entry, (((int64_t)bhfi->nFileIndexHigh) << 32)
+ bhfi->nFileIndexLow);
archive_entry_set_nlink(entry, bhfi->nNumberOfLinks);
archive_entry_set_size(entry, (((int64_t)bhfi->nFileSizeHigh) << 32)
+ bhfi->nFileSizeLow);
/* archive_entry_set_mode(entry, st->st_mode); */
}
#endif

View file

@ -0,0 +1,79 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_copy_stat.c 189466 2009-03-07 00:52:02Z kientzle $");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#include "archive.h"
#include "archive_entry.h"
void
archive_entry_copy_stat(struct archive_entry *entry, const struct stat *st)
{
#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
archive_entry_set_atime(entry, st->st_atime, st->st_atimespec.tv_nsec);
archive_entry_set_ctime(entry, st->st_ctime, st->st_ctimespec.tv_nsec);
archive_entry_set_mtime(entry, st->st_mtime, st->st_mtimespec.tv_nsec);
#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
archive_entry_set_atime(entry, st->st_atime, st->st_atim.tv_nsec);
archive_entry_set_ctime(entry, st->st_ctime, st->st_ctim.tv_nsec);
archive_entry_set_mtime(entry, st->st_mtime, st->st_mtim.tv_nsec);
#elif HAVE_STRUCT_STAT_ST_MTIME_N
archive_entry_set_atime(entry, st->st_atime, st->st_atime_n);
archive_entry_set_ctime(entry, st->st_ctime, st->st_ctime_n);
archive_entry_set_mtime(entry, st->st_mtime, st->st_mtime_n);
#elif HAVE_STRUCT_STAT_ST_UMTIME
archive_entry_set_atime(entry, st->st_atime, st->st_uatime * 1000);
archive_entry_set_ctime(entry, st->st_ctime, st->st_uctime * 1000);
archive_entry_set_mtime(entry, st->st_mtime, st->st_umtime * 1000);
#elif HAVE_STRUCT_STAT_ST_MTIME_USEC
archive_entry_set_atime(entry, st->st_atime, st->st_atime_usec * 1000);
archive_entry_set_ctime(entry, st->st_ctime, st->st_ctime_usec * 1000);
archive_entry_set_mtime(entry, st->st_mtime, st->st_mtime_usec * 1000);
#else
archive_entry_set_atime(entry, st->st_atime, 0);
archive_entry_set_ctime(entry, st->st_ctime, 0);
archive_entry_set_mtime(entry, st->st_mtime, 0);
#endif
#if HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC
archive_entry_set_birthtime(entry, st->st_birthtime, st->st_birthtimespec.tv_nsec);
#elif HAVE_STRUCT_STAT_ST_BIRTHTIME
archive_entry_set_birthtime(entry, st->st_birthtime, 0);
#else
archive_entry_unset_birthtime(entry);
#endif
archive_entry_set_dev(entry, st->st_dev);
archive_entry_set_gid(entry, st->st_gid);
archive_entry_set_uid(entry, st->st_uid);
archive_entry_set_ino(entry, st->st_ino);
archive_entry_set_nlink(entry, st->st_nlink);
archive_entry_set_rdev(entry, st->st_rdev);
archive_entry_set_size(entry, st->st_size);
archive_entry_set_mode(entry, st->st_mode);
}

View file

@ -0,0 +1,447 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_link_resolver.c 201100 2009-12-28 03:05:31Z kientzle $");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include "archive.h"
#include "archive_entry.h"
/*
* This is mostly a pretty straightforward hash table implementation.
* The only interesting bit is the different strategies used to
* match up links. These strategies match those used by various
* archiving formats:
* tar - content stored with first link, remainder refer back to it.
* This requires us to match each subsequent link up with the
* first appearance.
* cpio - Old cpio just stored body with each link, match-ups were
* implicit. This is trivial.
* new cpio - New cpio only stores body with last link, match-ups
* are implicit. This is actually quite tricky; see the notes
* below.
*/
/* Users pass us a format code, we translate that into a strategy here. */
#define ARCHIVE_ENTRY_LINKIFY_LIKE_TAR 0
#define ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE 1
#define ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO 2
#define ARCHIVE_ENTRY_LINKIFY_LIKE_NEW_CPIO 3
/* Initial size of link cache. */
#define links_cache_initial_size 1024
struct links_entry {
struct links_entry *next;
struct links_entry *previous;
struct archive_entry *canonical;
struct archive_entry *entry;
size_t hash;
unsigned int links; /* # links not yet seen */
};
struct archive_entry_linkresolver {
struct links_entry **buckets;
struct links_entry *spare;
unsigned long number_entries;
size_t number_buckets;
int strategy;
};
#define NEXT_ENTRY_DEFERRED 1
#define NEXT_ENTRY_PARTIAL 2
#define NEXT_ENTRY_ALL (NEXT_ENTRY_DEFERRED | NEXT_ENTRY_PARTIAL)
static struct links_entry *find_entry(struct archive_entry_linkresolver *,
struct archive_entry *);
static void grow_hash(struct archive_entry_linkresolver *);
static struct links_entry *insert_entry(struct archive_entry_linkresolver *,
struct archive_entry *);
static struct links_entry *next_entry(struct archive_entry_linkresolver *,
int);
struct archive_entry_linkresolver *
archive_entry_linkresolver_new(void)
{
struct archive_entry_linkresolver *res;
/* Check for positive power-of-two */
if (links_cache_initial_size == 0 ||
(links_cache_initial_size & (links_cache_initial_size - 1)) != 0)
return (NULL);
res = calloc(1, sizeof(struct archive_entry_linkresolver));
if (res == NULL)
return (NULL);
res->number_buckets = links_cache_initial_size;
res->buckets = calloc(res->number_buckets, sizeof(res->buckets[0]));
if (res->buckets == NULL) {
free(res);
return (NULL);
}
return (res);
}
void
archive_entry_linkresolver_set_strategy(struct archive_entry_linkresolver *res,
int fmt)
{
int fmtbase = fmt & ARCHIVE_FORMAT_BASE_MASK;
switch (fmtbase) {
case ARCHIVE_FORMAT_7ZIP:
case ARCHIVE_FORMAT_AR:
case ARCHIVE_FORMAT_ZIP:
res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO;
break;
case ARCHIVE_FORMAT_CPIO:
switch (fmt) {
case ARCHIVE_FORMAT_CPIO_SVR4_NOCRC:
case ARCHIVE_FORMAT_CPIO_SVR4_CRC:
res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_NEW_CPIO;
break;
default:
res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO;
break;
}
break;
case ARCHIVE_FORMAT_MTREE:
res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE;
break;
case ARCHIVE_FORMAT_ISO9660:
case ARCHIVE_FORMAT_SHAR:
case ARCHIVE_FORMAT_TAR:
case ARCHIVE_FORMAT_XAR:
res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_TAR;
break;
default:
res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO;
break;
}
}
void
archive_entry_linkresolver_free(struct archive_entry_linkresolver *res)
{
struct links_entry *le;
if (res == NULL)
return;
while ((le = next_entry(res, NEXT_ENTRY_ALL)) != NULL)
archive_entry_free(le->entry);
free(res->buckets);
free(res);
}
void
archive_entry_linkify(struct archive_entry_linkresolver *res,
struct archive_entry **e, struct archive_entry **f)
{
struct links_entry *le;
struct archive_entry *t;
*f = NULL; /* Default: Don't return a second entry. */
if (*e == NULL) {
le = next_entry(res, NEXT_ENTRY_DEFERRED);
if (le != NULL) {
*e = le->entry;
le->entry = NULL;
}
return;
}
/* If it has only one link, then we're done. */
if (archive_entry_nlink(*e) == 1)
return;
/* Directories, devices never have hardlinks. */
if (archive_entry_filetype(*e) == AE_IFDIR
|| archive_entry_filetype(*e) == AE_IFBLK
|| archive_entry_filetype(*e) == AE_IFCHR)
return;
switch (res->strategy) {
case ARCHIVE_ENTRY_LINKIFY_LIKE_TAR:
le = find_entry(res, *e);
if (le != NULL) {
archive_entry_unset_size(*e);
archive_entry_copy_hardlink(*e,
archive_entry_pathname(le->canonical));
} else
insert_entry(res, *e);
return;
case ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE:
le = find_entry(res, *e);
if (le != NULL) {
archive_entry_copy_hardlink(*e,
archive_entry_pathname(le->canonical));
} else
insert_entry(res, *e);
return;
case ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO:
/* This one is trivial. */
return;
case ARCHIVE_ENTRY_LINKIFY_LIKE_NEW_CPIO:
le = find_entry(res, *e);
if (le != NULL) {
/*
* Put the new entry in le, return the
* old entry from le.
*/
t = *e;
*e = le->entry;
le->entry = t;
/* Make the old entry into a hardlink. */
archive_entry_unset_size(*e);
archive_entry_copy_hardlink(*e,
archive_entry_pathname(le->canonical));
/* If we ran out of links, return the
* final entry as well. */
if (le->links == 0) {
*f = le->entry;
le->entry = NULL;
}
} else {
/*
* If we haven't seen it, tuck it away
* for future use.
*/
le = insert_entry(res, *e);
if (le == NULL)
/* XXX We should return an error code XXX */
return;
le->entry = *e;
*e = NULL;
}
return;
default:
break;
}
return;
}
static struct links_entry *
find_entry(struct archive_entry_linkresolver *res,
struct archive_entry *entry)
{
struct links_entry *le;
size_t hash, bucket;
dev_t dev;
int64_t ino;
/* Free a held entry. */
if (res->spare != NULL) {
archive_entry_free(res->spare->canonical);
archive_entry_free(res->spare->entry);
free(res->spare);
res->spare = NULL;
}
dev = archive_entry_dev(entry);
ino = archive_entry_ino64(entry);
hash = (size_t)(dev ^ ino);
/* Try to locate this entry in the links cache. */
bucket = hash & (res->number_buckets - 1);
for (le = res->buckets[bucket]; le != NULL; le = le->next) {
if (le->hash == hash
&& dev == archive_entry_dev(le->canonical)
&& ino == archive_entry_ino64(le->canonical)) {
/*
* Decrement link count each time and release
* the entry if it hits zero. This saves
* memory and is necessary for detecting
* missed links.
*/
--le->links;
if (le->links > 0)
return (le);
/* Remove it from this hash bucket. */
if (le->previous != NULL)
le->previous->next = le->next;
if (le->next != NULL)
le->next->previous = le->previous;
if (res->buckets[bucket] == le)
res->buckets[bucket] = le->next;
res->number_entries--;
/* Defer freeing this entry. */
res->spare = le;
return (le);
}
}
return (NULL);
}
static struct links_entry *
next_entry(struct archive_entry_linkresolver *res, int mode)
{
struct links_entry *le;
size_t bucket;
/* Free a held entry. */
if (res->spare != NULL) {
archive_entry_free(res->spare->canonical);
archive_entry_free(res->spare->entry);
free(res->spare);
res->spare = NULL;
}
/* Look for next non-empty bucket in the links cache. */
for (bucket = 0; bucket < res->number_buckets; bucket++) {
for (le = res->buckets[bucket]; le != NULL; le = le->next) {
if (le->entry != NULL &&
(mode & NEXT_ENTRY_DEFERRED) == 0)
continue;
if (le->entry == NULL &&
(mode & NEXT_ENTRY_PARTIAL) == 0)
continue;
/* Remove it from this hash bucket. */
if (le->next != NULL)
le->next->previous = le->previous;
if (le->previous != NULL)
le->previous->next = le->next;
else
res->buckets[bucket] = le->next;
res->number_entries--;
/* Defer freeing this entry. */
res->spare = le;
return (le);
}
}
return (NULL);
}
static struct links_entry *
insert_entry(struct archive_entry_linkresolver *res,
struct archive_entry *entry)
{
struct links_entry *le;
size_t hash, bucket;
/* Add this entry to the links cache. */
le = calloc(1, sizeof(struct links_entry));
if (le == NULL)
return (NULL);
le->canonical = archive_entry_clone(entry);
/* If the links cache is getting too full, enlarge the hash table. */
if (res->number_entries > res->number_buckets * 2)
grow_hash(res);
hash = (size_t)(archive_entry_dev(entry) ^ archive_entry_ino64(entry));
bucket = hash & (res->number_buckets - 1);
/* If we could allocate the entry, record it. */
if (res->buckets[bucket] != NULL)
res->buckets[bucket]->previous = le;
res->number_entries++;
le->next = res->buckets[bucket];
le->previous = NULL;
res->buckets[bucket] = le;
le->hash = hash;
le->links = archive_entry_nlink(entry) - 1;
return (le);
}
static void
grow_hash(struct archive_entry_linkresolver *res)
{
struct links_entry *le, **new_buckets;
size_t new_size;
size_t i, bucket;
/* Try to enlarge the bucket list. */
new_size = res->number_buckets * 2;
if (new_size < res->number_buckets)
return;
new_buckets = calloc(new_size, sizeof(struct links_entry *));
if (new_buckets == NULL)
return;
for (i = 0; i < res->number_buckets; i++) {
while (res->buckets[i] != NULL) {
/* Remove entry from old bucket. */
le = res->buckets[i];
res->buckets[i] = le->next;
/* Add entry to new bucket. */
bucket = le->hash & (new_size - 1);
if (new_buckets[bucket] != NULL)
new_buckets[bucket]->previous = le;
le->next = new_buckets[bucket];
le->previous = NULL;
new_buckets[bucket] = le;
}
}
free(res->buckets);
res->buckets = new_buckets;
res->number_buckets = new_size;
}
struct archive_entry *
archive_entry_partial_links(struct archive_entry_linkresolver *res,
unsigned int *links)
{
struct archive_entry *e;
struct links_entry *le;
/* Free a held entry. */
if (res->spare != NULL) {
archive_entry_free(res->spare->canonical);
archive_entry_free(res->spare->entry);
free(res->spare);
res->spare = NULL;
}
le = next_entry(res, NEXT_ENTRY_PARTIAL);
if (le != NULL) {
e = le->canonical;
if (links != NULL)
*links = le->links;
le->canonical = NULL;
} else {
e = NULL;
if (links != NULL)
*links = 0;
}
return (e);
}

View file

@ -0,0 +1,88 @@
/*-
* Copyright (c) 2011 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_ENTRY_LOCALE_H_INCLUDED
#define ARCHIVE_ENTRY_LOCALE_H_INCLUDED
struct archive_entry;
struct archive_string_conv;
/*
* Utility functions to set and get entry attributes by translating
* character-set. These are designed for use in format readers and writers.
*
* The return code and interface of these are quite different from other
* functions for archive_entry defined in archive_entry.h.
* Common return code are:
* Return 0 if the string conversion succeeded.
* Return -1 if the string conversion failed.
*/
#define archive_entry_gname_l _archive_entry_gname_l
int _archive_entry_gname_l(struct archive_entry *,
const char **, size_t *, struct archive_string_conv *);
#define archive_entry_hardlink_l _archive_entry_hardlink_l
int _archive_entry_hardlink_l(struct archive_entry *,
const char **, size_t *, struct archive_string_conv *);
#define archive_entry_pathname_l _archive_entry_pathname_l
int _archive_entry_pathname_l(struct archive_entry *,
const char **, size_t *, struct archive_string_conv *);
#define archive_entry_symlink_l _archive_entry_symlink_l
int _archive_entry_symlink_l(struct archive_entry *,
const char **, size_t *, struct archive_string_conv *);
#define archive_entry_uname_l _archive_entry_uname_l
int _archive_entry_uname_l(struct archive_entry *,
const char **, size_t *, struct archive_string_conv *);
#define archive_entry_acl_text_l _archive_entry_acl_text_l
int _archive_entry_acl_text_l(struct archive_entry *, int,
const char **, size_t *, struct archive_string_conv *);
#define archive_entry_copy_gname_l _archive_entry_copy_gname_l
int _archive_entry_copy_gname_l(struct archive_entry *,
const char *, size_t, struct archive_string_conv *);
#define archive_entry_copy_hardlink_l _archive_entry_copy_hardlink_l
int _archive_entry_copy_hardlink_l(struct archive_entry *,
const char *, size_t, struct archive_string_conv *);
#define archive_entry_copy_link_l _archive_entry_copy_link_l
int _archive_entry_copy_link_l(struct archive_entry *,
const char *, size_t, struct archive_string_conv *);
#define archive_entry_copy_pathname_l _archive_entry_copy_pathname_l
int _archive_entry_copy_pathname_l(struct archive_entry *,
const char *, size_t, struct archive_string_conv *);
#define archive_entry_copy_symlink_l _archive_entry_copy_symlink_l
int _archive_entry_copy_symlink_l(struct archive_entry *,
const char *, size_t, struct archive_string_conv *);
#define archive_entry_copy_uname_l _archive_entry_copy_uname_l
int _archive_entry_copy_uname_l(struct archive_entry *,
const char *, size_t, struct archive_string_conv *);
#endif /* ARCHIVE_ENTRY_LOCALE_H_INCLUDED */

View file

@ -0,0 +1,176 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: head/lib/libarchive/archive_entry_private.h 201096 2009-12-28 02:41:27Z kientzle $
*/
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
#define ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
#include "archive_acl_private.h"
#include "archive_string.h"
struct ae_xattr {
struct ae_xattr *next;
char *name;
void *value;
size_t size;
};
struct ae_sparse {
struct ae_sparse *next;
int64_t offset;
int64_t length;
};
/*
* Description of an archive entry.
*
* Basically, this is a "struct stat" with a few text fields added in.
*
* TODO: Add "comment", "charset", and possibly other entries
* that are supported by "pax interchange" format. However, GNU, ustar,
* cpio, and other variants don't support these features, so they're not an
* excruciatingly high priority right now.
*
* TODO: "pax interchange" format allows essentially arbitrary
* key/value attributes to be attached to any entry. Supporting
* such extensions may make this library useful for special
* applications (e.g., a package manager could attach special
* package-management attributes to each entry). There are tricky
* API issues involved, so this is not going to happen until
* there's a real demand for it.
*
* TODO: Design a good API for handling sparse files.
*/
struct archive_entry {
struct archive *archive;
/*
* Note that ae_stat.st_mode & AE_IFMT can be 0!
*
* This occurs when the actual file type of the object is not
* in the archive. For example, 'tar' archives store
* hardlinks without marking the type of the underlying
* object.
*/
/*
* We have a "struct aest" for holding file metadata rather than just
* a "struct stat" because on some platforms the "struct stat" has
* fields which are too narrow to hold the range of possible values;
* we don't want to lose information if we read an archive and write
* out another (e.g., in "tar -cf new.tar @old.tar").
*
* The "stat" pointer points to some form of platform-specific struct
* stat; it is declared as a void * rather than a struct stat * as
* some platforms have multiple varieties of stat structures.
*/
void *stat;
int stat_valid; /* Set to 0 whenever a field in aest changes. */
struct aest {
int64_t aest_atime;
uint32_t aest_atime_nsec;
int64_t aest_ctime;
uint32_t aest_ctime_nsec;
int64_t aest_mtime;
uint32_t aest_mtime_nsec;
int64_t aest_birthtime;
uint32_t aest_birthtime_nsec;
int64_t aest_gid;
int64_t aest_ino;
uint32_t aest_nlink;
uint64_t aest_size;
int64_t aest_uid;
/*
* Because converting between device codes and
* major/minor values is platform-specific and
* inherently a bit risky, we only do that conversion
* lazily. That way, we will do a better job of
* preserving information in those cases where no
* conversion is actually required.
*/
int aest_dev_is_broken_down;
dev_t aest_dev;
dev_t aest_devmajor;
dev_t aest_devminor;
int aest_rdev_is_broken_down;
dev_t aest_rdev;
dev_t aest_rdevmajor;
dev_t aest_rdevminor;
} ae_stat;
int ae_set; /* bitmap of fields that are currently set */
#define AE_SET_HARDLINK 1
#define AE_SET_SYMLINK 2
#define AE_SET_ATIME 4
#define AE_SET_CTIME 8
#define AE_SET_MTIME 16
#define AE_SET_BIRTHTIME 32
#define AE_SET_SIZE 64
#define AE_SET_INO 128
#define AE_SET_DEV 256
/*
* Use aes here so that we get transparent mbs<->wcs conversions.
*/
struct archive_mstring ae_fflags_text; /* Text fflags per fflagstostr(3) */
unsigned long ae_fflags_set; /* Bitmap fflags */
unsigned long ae_fflags_clear;
struct archive_mstring ae_gname; /* Name of owning group */
struct archive_mstring ae_hardlink; /* Name of target for hardlink */
struct archive_mstring ae_pathname; /* Name of entry */
struct archive_mstring ae_symlink; /* symlink contents */
struct archive_mstring ae_uname; /* Name of owner */
/* Not used within libarchive; useful for some clients. */
struct archive_mstring ae_sourcepath; /* Path this entry is sourced from. */
void *mac_metadata;
size_t mac_metadata_size;
/* ACL support. */
struct archive_acl acl;
/* extattr support. */
struct ae_xattr *xattr_head;
struct ae_xattr *xattr_p;
/* sparse support. */
struct ae_sparse *sparse_head;
struct ae_sparse *sparse_tail;
struct ae_sparse *sparse_p;
/* Miscellaneous. */
char strmode[12];
};
#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */

View file

@ -0,0 +1,156 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* Copyright (c) 2010-2011 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD$");
#include "archive.h"
#include "archive_entry.h"
#include "archive_private.h"
#include "archive_entry_private.h"
/*
* sparse handling
*/
void
archive_entry_sparse_clear(struct archive_entry *entry)
{
struct ae_sparse *sp;
while (entry->sparse_head != NULL) {
sp = entry->sparse_head->next;
free(entry->sparse_head);
entry->sparse_head = sp;
}
entry->sparse_tail = NULL;
}
void
archive_entry_sparse_add_entry(struct archive_entry *entry,
int64_t offset, int64_t length)
{
struct ae_sparse *sp;
if (offset < 0 || length < 0)
/* Invalid value */
return;
if (offset + length < 0 ||
offset + length > archive_entry_size(entry))
/* A value of "length" parameter is too large. */
return;
if ((sp = entry->sparse_tail) != NULL) {
if (sp->offset + sp->length > offset)
/* Invalid value. */
return;
if (sp->offset + sp->length == offset) {
if (sp->offset + sp->length + length < 0)
/* A value of "length" parameter is
* too large. */
return;
/* Expand existing sparse block size. */
sp->length += length;
return;
}
}
if ((sp = (struct ae_sparse *)malloc(sizeof(*sp))) == NULL)
/* XXX Error XXX */
return;
sp->offset = offset;
sp->length = length;
sp->next = NULL;
if (entry->sparse_head == NULL)
entry->sparse_head = entry->sparse_tail = sp;
else {
/* Add a new sparse block to the tail of list. */
if (entry->sparse_tail != NULL)
entry->sparse_tail->next = sp;
entry->sparse_tail = sp;
}
}
/*
* returns number of the sparse entries
*/
int
archive_entry_sparse_count(struct archive_entry *entry)
{
struct ae_sparse *sp;
int count = 0;
for (sp = entry->sparse_head; sp != NULL; sp = sp->next)
count++;
/*
* Sanity check if this entry is exactly sparse.
* If amount of sparse blocks is just one and it indicates the whole
* file data, we should remove it and return zero.
*/
if (count == 1) {
sp = entry->sparse_head;
if (sp->offset == 0 &&
sp->length >= archive_entry_size(entry)) {
count = 0;
archive_entry_sparse_clear(entry);
}
}
return (count);
}
int
archive_entry_sparse_reset(struct archive_entry * entry)
{
entry->sparse_p = entry->sparse_head;
return archive_entry_sparse_count(entry);
}
int
archive_entry_sparse_next(struct archive_entry * entry,
int64_t *offset, int64_t *length)
{
if (entry->sparse_p) {
*offset = entry->sparse_p->offset;
*length = entry->sparse_p->length;
entry->sparse_p = entry->sparse_p->next;
return (ARCHIVE_OK);
} else {
*offset = 0;
*length = 0;
return (ARCHIVE_WARN);
}
}
/*
* end of sparse handling
*/

View file

@ -0,0 +1,118 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_stat.c 201100 2009-12-28 03:05:31Z kientzle $");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include "archive_entry.h"
#include "archive_entry_private.h"
const struct stat *
archive_entry_stat(struct archive_entry *entry)
{
struct stat *st;
if (entry->stat == NULL) {
entry->stat = calloc(1, sizeof(*st));
if (entry->stat == NULL)
return (NULL);
entry->stat_valid = 0;
}
/*
* If none of the underlying fields have been changed, we
* don't need to regenerate. In theory, we could use a bitmap
* here to flag only those items that have changed, but the
* extra complexity probably isn't worth it. It will be very
* rare for anyone to change just one field then request a new
* stat structure.
*/
if (entry->stat_valid)
return (entry->stat);
st = entry->stat;
/*
* Use the public interfaces to extract items, so that
* the appropriate conversions get invoked.
*/
st->st_atime = archive_entry_atime(entry);
#if HAVE_STRUCT_STAT_ST_BIRTHTIME
st->st_birthtime = archive_entry_birthtime(entry);
#endif
st->st_ctime = archive_entry_ctime(entry);
st->st_mtime = archive_entry_mtime(entry);
st->st_dev = archive_entry_dev(entry);
st->st_gid = (gid_t)archive_entry_gid(entry);
st->st_uid = (uid_t)archive_entry_uid(entry);
st->st_ino = (ino_t)archive_entry_ino64(entry);
st->st_nlink = archive_entry_nlink(entry);
st->st_rdev = archive_entry_rdev(entry);
st->st_size = (off_t)archive_entry_size(entry);
st->st_mode = archive_entry_mode(entry);
/*
* On systems that support high-res timestamps, copy that
* information into struct stat.
*/
#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
st->st_atimespec.tv_nsec = archive_entry_atime_nsec(entry);
st->st_ctimespec.tv_nsec = archive_entry_ctime_nsec(entry);
st->st_mtimespec.tv_nsec = archive_entry_mtime_nsec(entry);
#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
st->st_atim.tv_nsec = archive_entry_atime_nsec(entry);
st->st_ctim.tv_nsec = archive_entry_ctime_nsec(entry);
st->st_mtim.tv_nsec = archive_entry_mtime_nsec(entry);
#elif HAVE_STRUCT_STAT_ST_MTIME_N
st->st_atime_n = archive_entry_atime_nsec(entry);
st->st_ctime_n = archive_entry_ctime_nsec(entry);
st->st_mtime_n = archive_entry_mtime_nsec(entry);
#elif HAVE_STRUCT_STAT_ST_UMTIME
st->st_uatime = archive_entry_atime_nsec(entry) / 1000;
st->st_uctime = archive_entry_ctime_nsec(entry) / 1000;
st->st_umtime = archive_entry_mtime_nsec(entry) / 1000;
#elif HAVE_STRUCT_STAT_ST_MTIME_USEC
st->st_atime_usec = archive_entry_atime_nsec(entry) / 1000;
st->st_ctime_usec = archive_entry_ctime_nsec(entry) / 1000;
st->st_mtime_usec = archive_entry_mtime_nsec(entry) / 1000;
#endif
#if HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC
st->st_birthtimespec.tv_nsec = archive_entry_birthtime_nsec(entry);
#endif
/*
* TODO: On Linux, store 32 or 64 here depending on whether
* the cached stat structure is a stat32 or a stat64. This
* will allow us to support both variants interchangeably.
*/
entry->stat_valid = 1;
return (st);
}

View file

@ -0,0 +1,87 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD: src/lib/libarchive/archive_entry_strmode.c,v 1.4 2008/06/15 05:14:01 kientzle Exp $");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include "archive_entry.h"
#include "archive_entry_private.h"
const char *
archive_entry_strmode(struct archive_entry *entry)
{
static const mode_t permbits[] =
{ 0400, 0200, 0100, 0040, 0020, 0010, 0004, 0002, 0001 };
char *bp = entry->strmode;
mode_t mode;
int i;
/* Fill in a default string, then selectively override. */
strcpy(bp, "?rwxrwxrwx ");
mode = archive_entry_mode(entry);
switch (archive_entry_filetype(entry)) {
case AE_IFREG: bp[0] = '-'; break;
case AE_IFBLK: bp[0] = 'b'; break;
case AE_IFCHR: bp[0] = 'c'; break;
case AE_IFDIR: bp[0] = 'd'; break;
case AE_IFLNK: bp[0] = 'l'; break;
case AE_IFSOCK: bp[0] = 's'; break;
case AE_IFIFO: bp[0] = 'p'; break;
default:
if (archive_entry_hardlink(entry) != NULL) {
bp[0] = 'h';
break;
}
}
for (i = 0; i < 9; i++)
if (!(mode & permbits[i]))
bp[i+1] = '-';
if (mode & S_ISUID) {
if (mode & 0100) bp[3] = 's';
else bp[3] = 'S';
}
if (mode & S_ISGID) {
if (mode & 0010) bp[6] = 's';
else bp[6] = 'S';
}
if (mode & S_ISVTX) {
if (mode & 0001) bp[9] = 't';
else bp[9] = 'T';
}
if (archive_entry_acl_count(entry, ARCHIVE_ENTRY_ACL_TYPE_ACCESS))
bp[10] = '+';
return (bp);
}

View file

@ -0,0 +1,158 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_xattr.c 201096 2009-12-28 02:41:27Z kientzle $");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifdef HAVE_LINUX_FS_H
#include <linux/fs.h> /* for Linux file flags */
#endif
/*
* Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
* As the include guards don't agree, the order of include is important.
*/
#ifdef HAVE_LINUX_EXT2_FS_H
#include <linux/ext2_fs.h> /* for Linux file flags */
#endif
#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
#include <ext2fs/ext2_fs.h> /* for Linux file flags */
#endif
#include <stddef.h>
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_WCHAR_H
#include <wchar.h>
#endif
#include "archive.h"
#include "archive_entry.h"
#include "archive_private.h"
#include "archive_entry_private.h"
/*
* extended attribute handling
*/
void
archive_entry_xattr_clear(struct archive_entry *entry)
{
struct ae_xattr *xp;
while (entry->xattr_head != NULL) {
xp = entry->xattr_head->next;
free(entry->xattr_head->name);
free(entry->xattr_head->value);
free(entry->xattr_head);
entry->xattr_head = xp;
}
entry->xattr_head = NULL;
}
void
archive_entry_xattr_add_entry(struct archive_entry *entry,
const char *name, const void *value, size_t size)
{
struct ae_xattr *xp;
for (xp = entry->xattr_head; xp != NULL; xp = xp->next)
;
if ((xp = (struct ae_xattr *)malloc(sizeof(struct ae_xattr))) == NULL)
/* XXX Error XXX */
return;
xp->name = strdup(name);
if ((xp->value = malloc(size)) != NULL) {
memcpy(xp->value, value, size);
xp->size = size;
} else
xp->size = 0;
xp->next = entry->xattr_head;
entry->xattr_head = xp;
}
/*
* returns number of the extended attribute entries
*/
int
archive_entry_xattr_count(struct archive_entry *entry)
{
struct ae_xattr *xp;
int count = 0;
for (xp = entry->xattr_head; xp != NULL; xp = xp->next)
count++;
return count;
}
int
archive_entry_xattr_reset(struct archive_entry * entry)
{
entry->xattr_p = entry->xattr_head;
return archive_entry_xattr_count(entry);
}
int
archive_entry_xattr_next(struct archive_entry * entry,
const char **name, const void **value, size_t *size)
{
if (entry->xattr_p) {
*name = entry->xattr_p->name;
*value = entry->xattr_p->value;
*size = entry->xattr_p->size;
entry->xattr_p = entry->xattr_p->next;
return (ARCHIVE_OK);
} else {
*name = NULL;
*value = NULL;
*size = (size_t)0;
return (ARCHIVE_WARN);
}
}
/*
* end of xattr handling
*/

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,211 @@
/*-
* Copyright (c) 2011 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD$");
#include "archive_options_private.h"
static const char *
parse_option(const char **str,
const char **mod, const char **opt, const char **val);
int
_archive_set_option(struct archive *a,
const char *m, const char *o, const char *v,
int magic, const char *fn, option_handler use_option)
{
const char *mp, *op, *vp;
int r;
archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
mp = m != NULL && m[0] == '\0' ? NULL : m;
op = o != NULL && o[0] == '\0' ? NULL : o;
vp = v != NULL && v[0] == '\0' ? NULL : v;
if (op == NULL && vp == NULL)
return (ARCHIVE_OK);
if (op == NULL) {
archive_set_error(a, ARCHIVE_ERRNO_MISC, "Empty option");
return (ARCHIVE_FAILED);
}
r = use_option(a, mp, op, vp);
if (r == ARCHIVE_WARN - 1) {
archive_set_error(a, ARCHIVE_ERRNO_MISC,
"Unknown module name: `%s'", mp);
return (ARCHIVE_FAILED);
}
if (r == ARCHIVE_WARN) {
archive_set_error(a, ARCHIVE_ERRNO_MISC,
"Undefined option: `%s%s%s%s%s%s'",
vp?"":"!", mp?mp:"", mp?":":"", op, vp?"=":"", vp?vp:"");
return (ARCHIVE_FAILED);
}
return (r);
}
int
_archive_set_either_option(struct archive *a, const char *m, const char *o, const char *v,
option_handler use_format_option, option_handler use_filter_option)
{
int r1, r2;
if (o == NULL && v == NULL)
return (ARCHIVE_OK);
if (o == NULL)
return (ARCHIVE_FAILED);
r1 = use_format_option(a, m, o, v);
if (r1 == ARCHIVE_FATAL)
return (ARCHIVE_FATAL);
r2 = use_filter_option(a, m, o, v);
if (r2 == ARCHIVE_FATAL)
return (ARCHIVE_FATAL);
if (r2 == ARCHIVE_WARN - 1)
return r1;
return r1 > r2 ? r1 : r2;
}
int
_archive_set_options(struct archive *a, const char *options,
int magic, const char *fn, option_handler use_option)
{
int allok = 1, anyok = 0, ignore_mod_err = 0, r;
char *data;
const char *s, *mod, *opt, *val;
archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
if (options == NULL || options[0] == '\0')
return ARCHIVE_OK;
data = (char *)malloc(strlen(options) + 1);
strcpy(data, options);
s = (const char *)data;
do {
mod = opt = val = NULL;
parse_option(&s, &mod, &opt, &val);
if (mod == NULL && opt != NULL &&
strcmp("__ignore_wrong_module_name__", opt) == 0) {
/* Ignore module name error */
if (val != NULL) {
ignore_mod_err = 1;
anyok = 1;
}
continue;
}
r = use_option(a, mod, opt, val);
if (r == ARCHIVE_FATAL) {
free(data);
return (ARCHIVE_FATAL);
}
if (r == ARCHIVE_FAILED && mod != NULL) {
free(data);
return (ARCHIVE_FAILED);
}
if (r == ARCHIVE_WARN - 1) {
if (ignore_mod_err)
continue;
/* The module name is wrong. */
archive_set_error(a, ARCHIVE_ERRNO_MISC,
"Unknown module name: `%s'", mod);
free(data);
return (ARCHIVE_FAILED);
}
if (r == ARCHIVE_WARN) {
/* The option name is wrong. No-one used this. */
archive_set_error(a, ARCHIVE_ERRNO_MISC,
"Undefined option: `%s%s%s'",
mod?mod:"", mod?":":"", opt);
free(data);
return (ARCHIVE_FAILED);
}
if (r == ARCHIVE_OK)
anyok = 1;
else
allok = 0;
} while (s != NULL);
free(data);
return allok ? ARCHIVE_OK : anyok ? ARCHIVE_WARN : ARCHIVE_FAILED;
}
static const char *
parse_option(const char **s, const char **m, const char **o, const char **v)
{
const char *end, *mod, *opt, *val;
char *p;
end = NULL;
mod = NULL;
opt = *s;
val = "1";
p = strchr(opt, ',');
if (p != NULL) {
*p = '\0';
end = ((const char *)p) + 1;
}
if (0 == strlen(opt)) {
*s = end;
*m = NULL;
*o = NULL;
*v = NULL;
return end;
}
p = strchr(opt, ':');
if (p != NULL) {
*p = '\0';
mod = opt;
opt = ++p;
}
p = strchr(opt, '=');
if (p != NULL) {
*p = '\0';
val = ++p;
} else if (opt[0] == '!') {
++opt;
val = NULL;
}
*s = end;
*m = mod;
*o = opt;
*v = val;
return end;
}

View file

@ -0,0 +1,47 @@
/*-
* Copyright (c) 2011 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD$");
#include "archive_private.h"
typedef int (*option_handler)(struct archive *a,
const char *mod, const char *opt, const char *val);
int
_archive_set_option(struct archive *a,
const char *mod, const char *opt, const char *val,
int magic, const char *fn, option_handler use_option);
int
_archive_set_options(struct archive *a, const char *options,
int magic, const char *fn, option_handler use_option);
int
_archive_set_either_option(struct archive *a,
const char *m, const char *o, const char *v,
option_handler use_format_option, option_handler use_filter_option);

View file

@ -0,0 +1,459 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD$");
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_WCHAR_H
#include <wchar.h>
#endif
#include "archive_pathmatch.h"
/*
* Check whether a character 'c' is matched by a list specification [...]:
* * Leading '!' or '^' negates the class.
* * <char>-<char> is a range of characters
* * \<char> removes any special meaning for <char>
*
* Some interesting boundary cases:
* a-d-e is one range (a-d) followed by two single characters - and e.
* \a-\d is same as a-d
* a\-d is three single characters: a, d, -
* Trailing - is not special (so [a-] is two characters a and -).
* Initial - is not special ([a-] is same as [-a] is same as [\\-a])
* This function never sees a trailing \.
* [] always fails
* [!] always succeeds
*/
static int
pm_list(const char *start, const char *end, const char c, int flags)
{
const char *p = start;
char rangeStart = '\0', nextRangeStart;
int match = 1, nomatch = 0;
/* This will be used soon... */
(void)flags; /* UNUSED */
/* If this is a negated class, return success for nomatch. */
if ((*p == '!' || *p == '^') && p < end) {
match = 0;
nomatch = 1;
++p;
}
while (p < end) {
nextRangeStart = '\0';
switch (*p) {
case '-':
/* Trailing or initial '-' is not special. */
if ((rangeStart == '\0') || (p == end - 1)) {
if (*p == c)
return (match);
} else {
char rangeEnd = *++p;
if (rangeEnd == '\\')
rangeEnd = *++p;
if ((rangeStart <= c) && (c <= rangeEnd))
return (match);
}
break;
case '\\':
++p;
/* Fall through */
default:
if (*p == c)
return (match);
nextRangeStart = *p; /* Possible start of range. */
}
rangeStart = nextRangeStart;
++p;
}
return (nomatch);
}
static int
pm_list_w(const wchar_t *start, const wchar_t *end, const wchar_t c, int flags)
{
const wchar_t *p = start;
wchar_t rangeStart = L'\0', nextRangeStart;
int match = 1, nomatch = 0;
/* This will be used soon... */
(void)flags; /* UNUSED */
/* If this is a negated class, return success for nomatch. */
if ((*p == L'!' || *p == L'^') && p < end) {
match = 0;
nomatch = 1;
++p;
}
while (p < end) {
nextRangeStart = L'\0';
switch (*p) {
case L'-':
/* Trailing or initial '-' is not special. */
if ((rangeStart == L'\0') || (p == end - 1)) {
if (*p == c)
return (match);
} else {
wchar_t rangeEnd = *++p;
if (rangeEnd == L'\\')
rangeEnd = *++p;
if ((rangeStart <= c) && (c <= rangeEnd))
return (match);
}
break;
case L'\\':
++p;
/* Fall through */
default:
if (*p == c)
return (match);
nextRangeStart = *p; /* Possible start of range. */
}
rangeStart = nextRangeStart;
++p;
}
return (nomatch);
}
/*
* If s is pointing to "./", ".//", "./././" or the like, skip it.
*/
static const char *
pm_slashskip(const char *s) {
while ((*s == '/')
|| (s[0] == '.' && s[1] == '/')
|| (s[0] == '.' && s[1] == '\0'))
++s;
return (s);
}
static const wchar_t *
pm_slashskip_w(const wchar_t *s) {
while ((*s == L'/')
|| (s[0] == L'.' && s[1] == L'/')
|| (s[0] == L'.' && s[1] == L'\0'))
++s;
return (s);
}
static int
pm(const char *p, const char *s, int flags)
{
const char *end;
/*
* Ignore leading './', './/', '././', etc.
*/
if (s[0] == '.' && s[1] == '/')
s = pm_slashskip(s + 1);
if (p[0] == '.' && p[1] == '/')
p = pm_slashskip(p + 1);
for (;;) {
switch (*p) {
case '\0':
if (s[0] == '/') {
if (flags & PATHMATCH_NO_ANCHOR_END)
return (1);
/* "dir" == "dir/" == "dir/." */
s = pm_slashskip(s);
}
return (*s == '\0');
case '?':
/* ? always succeeds, unless we hit end of 's' */
if (*s == '\0')
return (0);
break;
case '*':
/* "*" == "**" == "***" ... */
while (*p == '*')
++p;
/* Trailing '*' always succeeds. */
if (*p == '\0')
return (1);
while (*s) {
if (archive_pathmatch(p, s, flags))
return (1);
++s;
}
return (0);
case '[':
/*
* Find the end of the [...] character class,
* ignoring \] that might occur within the class.
*/
end = p + 1;
while (*end != '\0' && *end != ']') {
if (*end == '\\' && end[1] != '\0')
++end;
++end;
}
if (*end == ']') {
/* We found [...], try to match it. */
if (!pm_list(p + 1, end, *s, flags))
return (0);
p = end; /* Jump to trailing ']' char. */
break;
} else
/* No final ']', so just match '['. */
if (*p != *s)
return (0);
break;
case '\\':
/* Trailing '\\' matches itself. */
if (p[1] == '\0') {
if (*s != '\\')
return (0);
} else {
++p;
if (*p != *s)
return (0);
}
break;
case '/':
if (*s != '/' && *s != '\0')
return (0);
/* Note: pattern "/\./" won't match "/";
* pm_slashskip() correctly stops at backslash. */
p = pm_slashskip(p);
s = pm_slashskip(s);
if (*p == '\0' && (flags & PATHMATCH_NO_ANCHOR_END))
return (1);
--p; /* Counteract the increment below. */
--s;
break;
case '$':
/* '$' is special only at end of pattern and only
* if PATHMATCH_NO_ANCHOR_END is specified. */
if (p[1] == '\0' && (flags & PATHMATCH_NO_ANCHOR_END)){
/* "dir" == "dir/" == "dir/." */
return (*pm_slashskip(s) == '\0');
}
/* Otherwise, '$' is not special. */
/* FALL THROUGH */
default:
if (*p != *s)
return (0);
break;
}
++p;
++s;
}
}
static int
pm_w(const wchar_t *p, const wchar_t *s, int flags)
{
const wchar_t *end;
/*
* Ignore leading './', './/', '././', etc.
*/
if (s[0] == L'.' && s[1] == L'/')
s = pm_slashskip_w(s + 1);
if (p[0] == L'.' && p[1] == L'/')
p = pm_slashskip_w(p + 1);
for (;;) {
switch (*p) {
case L'\0':
if (s[0] == L'/') {
if (flags & PATHMATCH_NO_ANCHOR_END)
return (1);
/* "dir" == "dir/" == "dir/." */
s = pm_slashskip_w(s);
}
return (*s == L'\0');
case L'?':
/* ? always succeeds, unless we hit end of 's' */
if (*s == L'\0')
return (0);
break;
case L'*':
/* "*" == "**" == "***" ... */
while (*p == L'*')
++p;
/* Trailing '*' always succeeds. */
if (*p == L'\0')
return (1);
while (*s) {
if (archive_pathmatch_w(p, s, flags))
return (1);
++s;
}
return (0);
case L'[':
/*
* Find the end of the [...] character class,
* ignoring \] that might occur within the class.
*/
end = p + 1;
while (*end != L'\0' && *end != L']') {
if (*end == L'\\' && end[1] != L'\0')
++end;
++end;
}
if (*end == L']') {
/* We found [...], try to match it. */
if (!pm_list_w(p + 1, end, *s, flags))
return (0);
p = end; /* Jump to trailing ']' char. */
break;
} else
/* No final ']', so just match '['. */
if (*p != *s)
return (0);
break;
case L'\\':
/* Trailing '\\' matches itself. */
if (p[1] == L'\0') {
if (*s != L'\\')
return (0);
} else {
++p;
if (*p != *s)
return (0);
}
break;
case L'/':
if (*s != L'/' && *s != L'\0')
return (0);
/* Note: pattern "/\./" won't match "/";
* pm_slashskip() correctly stops at backslash. */
p = pm_slashskip_w(p);
s = pm_slashskip_w(s);
if (*p == L'\0' && (flags & PATHMATCH_NO_ANCHOR_END))
return (1);
--p; /* Counteract the increment below. */
--s;
break;
case L'$':
/* '$' is special only at end of pattern and only
* if PATHMATCH_NO_ANCHOR_END is specified. */
if (p[1] == L'\0' && (flags & PATHMATCH_NO_ANCHOR_END)){
/* "dir" == "dir/" == "dir/." */
return (*pm_slashskip_w(s) == L'\0');
}
/* Otherwise, '$' is not special. */
/* FALL THROUGH */
default:
if (*p != *s)
return (0);
break;
}
++p;
++s;
}
}
/* Main entry point. */
int
__archive_pathmatch(const char *p, const char *s, int flags)
{
/* Empty pattern only matches the empty string. */
if (p == NULL || *p == '\0')
return (s == NULL || *s == '\0');
/* Leading '^' anchors the start of the pattern. */
if (*p == '^') {
++p;
flags &= ~PATHMATCH_NO_ANCHOR_START;
}
if (*p == '/' && *s != '/')
return (0);
/* Certain patterns and file names anchor implicitly. */
if (*p == '*' || *p == '/' || *p == '/') {
while (*p == '/')
++p;
while (*s == '/')
++s;
return (pm(p, s, flags));
}
/* If start is unanchored, try to match start of each path element. */
if (flags & PATHMATCH_NO_ANCHOR_START) {
for ( ; s != NULL; s = strchr(s, '/')) {
if (*s == '/')
s++;
if (pm(p, s, flags))
return (1);
}
return (0);
}
/* Default: Match from beginning. */
return (pm(p, s, flags));
}
int
__archive_pathmatch_w(const wchar_t *p, const wchar_t *s, int flags)
{
/* Empty pattern only matches the empty string. */
if (p == NULL || *p == L'\0')
return (s == NULL || *s == L'\0');
/* Leading '^' anchors the start of the pattern. */
if (*p == L'^') {
++p;
flags &= ~PATHMATCH_NO_ANCHOR_START;
}
if (*p == L'/' && *s != L'/')
return (0);
/* Certain patterns and file names anchor implicitly. */
if (*p == L'*' || *p == L'/' || *p == L'/') {
while (*p == L'/')
++p;
while (*s == L'/')
++s;
return (pm_w(p, s, flags));
}
/* If start is unanchored, try to match start of each path element. */
if (flags & PATHMATCH_NO_ANCHOR_START) {
for ( ; s != NULL; s = wcschr(s, L'/')) {
if (*s == L'/')
s++;
if (pm_w(p, s, flags))
return (1);
}
return (0);
}
/* Default: Match from beginning. */
return (pm_w(p, s, flags));
}

View file

@ -0,0 +1,52 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef __LIBARCHIVE_BUILD
#ifndef __LIBARCHIVE_TEST
#error This header is only to be used internally to libarchive.
#endif
#endif
#ifndef ARCHIVE_PATHMATCH_H
#define ARCHIVE_PATHMATCH_H
/* Don't anchor at beginning unless the pattern starts with "^" */
#define PATHMATCH_NO_ANCHOR_START 1
/* Don't anchor at end unless the pattern ends with "$" */
#define PATHMATCH_NO_ANCHOR_END 2
/* Note that "^" and "$" are not special unless you set the corresponding
* flag above. */
int __archive_pathmatch(const char *p, const char *s, int flags);
int __archive_pathmatch_w(const wchar_t *p, const wchar_t *s, int flags);
#define archive_pathmatch(p, s, f) __archive_pathmatch(p, s, f)
#define archive_pathmatch_w(p, s, f) __archive_pathmatch_w(p, s, f)
#endif

View file

@ -0,0 +1,165 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: head/lib/libarchive/archive_platform.h 201090 2009-12-28 02:22:04Z kientzle $
*/
/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */
/*
* This header is the first thing included in any of the libarchive
* source files. As far as possible, platform-specific issues should
* be dealt with here and not within individual source files. I'm
* actively trying to minimize #if blocks within the main source,
* since they obfuscate the code.
*/
#ifndef ARCHIVE_PLATFORM_H_INCLUDED
#define ARCHIVE_PLATFORM_H_INCLUDED
/* archive.h and archive_entry.h require this. */
#define __LIBARCHIVE_BUILD 1
#if defined(PLATFORM_CONFIG_H)
/* Use hand-built config.h in environments that need it. */
#include PLATFORM_CONFIG_H
#elif defined(HAVE_CONFIG_H)
/* Most POSIX platforms use the 'configure' script to build config.h */
#include "config.h"
#else
/* Warn if the library hasn't been (automatically or manually) configured. */
#error Oops: No config.h and no pre-built configuration in archive_platform.h.
#endif
/* It should be possible to get rid of this by extending the feature-test
* macros to cover Windows API functions, probably along with non-trivial
* refactoring of code to find structures that sit more cleanly on top of
* either Windows or Posix APIs. */
#if (defined(__WIN32__) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__)
#include "archive_windows.h"
#endif
/*
* The config files define a lot of feature macros. The following
* uses those macros to select/define replacements and include key
* headers as required.
*/
/* Get a real definition for __FBSDID if we can */
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
/* If not, define it so as to avoid dangling semicolons. */
#ifndef __FBSDID
#define __FBSDID(a) struct _undefined_hack
#endif
/* Try to get standard C99-style integer type definitions. */
#if HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#if HAVE_STDINT_H
#include <stdint.h>
#endif
/* Borland warns about its own constants! */
#if defined(__BORLANDC__)
# if HAVE_DECL_UINT64_MAX
# undef UINT64_MAX
# undef HAVE_DECL_UINT64_MAX
# endif
# if HAVE_DECL_UINT64_MIN
# undef UINT64_MIN
# undef HAVE_DECL_UINT64_MIN
# endif
# if HAVE_DECL_INT64_MAX
# undef INT64_MAX
# undef HAVE_DECL_INT64_MAX
# endif
# if HAVE_DECL_INT64_MIN
# undef INT64_MIN
# undef HAVE_DECL_INT64_MIN
# endif
#endif
/* Some platforms lack the standard *_MAX definitions. */
#if !HAVE_DECL_SIZE_MAX
#define SIZE_MAX (~(size_t)0)
#endif
#if !HAVE_DECL_SSIZE_MAX
#define SSIZE_MAX ((ssize_t)(SIZE_MAX >> 1))
#endif
#if !HAVE_DECL_UINT32_MAX
#define UINT32_MAX (~(uint32_t)0)
#endif
#if !HAVE_DECL_UINT64_MAX
#define UINT64_MAX (~(uint64_t)0)
#endif
#if !HAVE_DECL_INT64_MAX
#define INT64_MAX ((int64_t)(UINT64_MAX >> 1))
#endif
#if !HAVE_DECL_INT64_MIN
#define INT64_MIN ((int64_t)(~INT64_MAX))
#endif
/*
* If this platform has <sys/acl.h>, acl_create(), acl_init(),
* acl_set_file(), and ACL_USER, we assume it has the rest of the
* POSIX.1e draft functions used in archive_read_extract.c.
*/
#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE && HAVE_ACL_USER
#define HAVE_POSIX_ACL 1
#endif
/*
* If we can't restore metadata using a file descriptor, then
* for compatibility's sake, close files before trying to restore metadata.
*/
#if defined(HAVE_FCHMOD) || defined(HAVE_FUTIMES) || defined(HAVE_ACL_SET_FD) || defined(HAVE_ACL_SET_FD_NP) || defined(HAVE_FCHOWN)
#define CAN_RESTORE_METADATA_FD
#endif
/* Set up defaults for internal error codes. */
#ifndef ARCHIVE_ERRNO_FILE_FORMAT
#if HAVE_EFTYPE
#define ARCHIVE_ERRNO_FILE_FORMAT EFTYPE
#else
#if HAVE_EILSEQ
#define ARCHIVE_ERRNO_FILE_FORMAT EILSEQ
#else
#define ARCHIVE_ERRNO_FILE_FORMAT EINVAL
#endif
#endif
#endif
#ifndef ARCHIVE_ERRNO_PROGRAMMER
#define ARCHIVE_ERRNO_PROGRAMMER EINVAL
#endif
#ifndef ARCHIVE_ERRNO_MISC
#define ARCHIVE_ERRNO_MISC (-1)
#endif
#endif /* !ARCHIVE_PLATFORM_H_INCLUDED */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,119 @@
/* Ppmd7.h -- PPMdH compression codec
2010-03-12 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
/* This code supports virtual RangeDecoder and includes the implementation
of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H.
If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
#define ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
#include "archive_ppmd_private.h"
#define PPMD7_MIN_ORDER 2
#define PPMD7_MAX_ORDER 64
#define PPMD7_MIN_MEM_SIZE (1 << 11)
#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3)
struct CPpmd7_Context_;
typedef
#ifdef PPMD_32BIT
struct CPpmd7_Context_ *
#else
UInt32
#endif
CPpmd7_Context_Ref;
typedef struct CPpmd7_Context_
{
UInt16 NumStats;
UInt16 SummFreq;
CPpmd_State_Ref Stats;
CPpmd7_Context_Ref Suffix;
} CPpmd7_Context;
#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
typedef struct
{
CPpmd7_Context *MinContext, *MaxContext;
CPpmd_State *FoundState;
unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag;
Int32 RunLength, InitRL; /* must be 32-bit at least */
UInt32 Size;
UInt32 GlueCount;
Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
UInt32 AlignOffset;
Byte Indx2Units[PPMD_NUM_INDEXES];
Byte Units2Indx[128];
CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
CPpmd_See DummySee, See[25][16];
UInt16 BinSumm[128][64];
} CPpmd7;
/* ---------- Decode ---------- */
typedef struct
{
UInt32 (*GetThreshold)(void *p, UInt32 total);
void (*Decode)(void *p, UInt32 start, UInt32 size);
UInt32 (*DecodeBit)(void *p, UInt32 size0);
} IPpmd7_RangeDec;
typedef struct
{
IPpmd7_RangeDec p;
UInt32 Range;
UInt32 Code;
UInt32 Low;
UInt32 Bottom;
IByteIn *Stream;
} CPpmd7z_RangeDec;
/* ---------- Encode ---------- */
typedef struct
{
UInt64 Low;
UInt32 Range;
Byte Cache;
UInt64 CacheSize;
IByteOut *Stream;
} CPpmd7z_RangeEnc;
typedef struct
{
/* Base Functions */
void (*Ppmd7_Construct)(CPpmd7 *p);
Bool (*Ppmd7_Alloc)(CPpmd7 *p, UInt32 size, ISzAlloc *alloc);
void (*Ppmd7_Free)(CPpmd7 *p, ISzAlloc *alloc);
void (*Ppmd7_Init)(CPpmd7 *p, unsigned maxOrder);
#define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
/* Decode Functions */
void (*Ppmd7z_RangeDec_CreateVTable)(CPpmd7z_RangeDec *p);
void (*PpmdRAR_RangeDec_CreateVTable)(CPpmd7z_RangeDec *p);
Bool (*Ppmd7z_RangeDec_Init)(CPpmd7z_RangeDec *p);
Bool (*PpmdRAR_RangeDec_Init)(CPpmd7z_RangeDec *p);
#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
int (*Ppmd7_DecodeSymbol)(CPpmd7 *p, IPpmd7_RangeDec *rc);
/* Encode Functions */
void (*Ppmd7z_RangeEnc_Init)(CPpmd7z_RangeEnc *p);
void (*Ppmd7z_RangeEnc_FlushData)(CPpmd7z_RangeEnc *p);
void (*Ppmd7_EncodeSymbol)(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol);
} IPpmd7;
extern const IPpmd7 __archive_ppmd7_functions;
#endif

View file

@ -0,0 +1,158 @@
/* Ppmd.h -- PPMD codec common code
2010-03-12 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_PPMD_PRIVATE_H_INCLUDED
#define ARCHIVE_PPMD_PRIVATE_H_INCLUDED
#include <stddef.h>
#include "archive_read_private.h"
/*** Begin defined in Types.h ***/
#if !defined(ZCONF_H)
typedef unsigned char Byte;
#endif
typedef short Int16;
typedef unsigned short UInt16;
#ifdef _LZMA_UINT32_IS_ULONG
typedef long Int32;
typedef unsigned long UInt32;
#else
typedef int Int32;
typedef unsigned int UInt32;
#endif
#ifdef _SZ_NO_INT_64
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
NOTES: Some code will work incorrectly in that case! */
typedef long Int64;
typedef unsigned long UInt64;
#else
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
#define UINT64_CONST(n) n
#else
typedef long long int Int64;
typedef unsigned long long int UInt64;
#define UINT64_CONST(n) n ## ULL
#endif
#endif
typedef int Bool;
#define True 1
#define False 0
/* The following interfaces use first parameter as pointer to structure */
typedef struct
{
struct archive_read *a;
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
} IByteIn;
typedef struct
{
struct archive_write *a;
void (*Write)(void *p, Byte b);
} IByteOut;
typedef struct
{
void *(*Alloc)(void *p, size_t size);
void (*Free)(void *p, void *address); /* address can be 0 */
} ISzAlloc;
/*** End defined in Types.h ***/
/*** Begin defined in CpuArch.h ***/
#if defined(_M_IX86) || defined(__i386__)
#define MY_CPU_X86
#endif
#if defined(MY_CPU_X86) || defined(_M_ARM)
#define MY_CPU_32BIT
#endif
#ifdef MY_CPU_32BIT
#define PPMD_32BIT
#endif
/*** End defined in CpuArch.h ***/
#define PPMD_INT_BITS 7
#define PPMD_PERIOD_BITS 7
#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS))
#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift))
#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2)
#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob))
#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob))
#define PPMD_N1 4
#define PPMD_N2 4
#define PPMD_N3 4
#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4)
#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4)
/* SEE-contexts for PPM-contexts with masked symbols */
typedef struct
{
UInt16 Summ; /* Freq */
Byte Shift; /* Speed of Freq change; low Shift is for fast change */
Byte Count; /* Count to next change of Shift */
} CPpmd_See;
#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \
{ (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); }
typedef struct
{
Byte Symbol;
Byte Freq;
UInt16 SuccessorLow;
UInt16 SuccessorHigh;
} CPpmd_State;
typedef
#ifdef PPMD_32BIT
CPpmd_State *
#else
UInt32
#endif
CPpmd_State_Ref;
typedef
#ifdef PPMD_32BIT
void *
#else
UInt32
#endif
CPpmd_Void_Ref;
typedef
#ifdef PPMD_32BIT
Byte *
#else
UInt32
#endif
CPpmd_Byte_Ref;
#define PPMD_SetAllBitsIn256Bytes(p) \
{ unsigned j; for (j = 0; j < 256 / sizeof(p[0]); j += 8) { \
p[j+7] = p[j+6] = p[j+5] = p[j+4] = p[j+3] = p[j+2] = p[j+1] = p[j+0] = ~(size_t)0; }}
#endif

View file

@ -0,0 +1,152 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: head/lib/libarchive/archive_private.h 201098 2009-12-28 02:58:14Z kientzle $
*/
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_PRIVATE_H_INCLUDED
#define ARCHIVE_PRIVATE_H_INCLUDED
#if HAVE_ICONV_H
#include <iconv.h>
#endif
#include "archive.h"
#include "archive_string.h"
#if defined(__GNUC__) && (__GNUC__ > 2 || \
(__GNUC__ == 2 && __GNUC_MINOR__ >= 5))
#define __LA_DEAD __attribute__((__noreturn__))
#else
#define __LA_DEAD
#endif
#define ARCHIVE_WRITE_MAGIC (0xb0c5c0deU)
#define ARCHIVE_READ_MAGIC (0xdeb0c5U)
#define ARCHIVE_WRITE_DISK_MAGIC (0xc001b0c5U)
#define ARCHIVE_READ_DISK_MAGIC (0xbadb0c5U)
#define ARCHIVE_MATCH_MAGIC (0xcad11c9U)
#define ARCHIVE_STATE_NEW 1U
#define ARCHIVE_STATE_HEADER 2U
#define ARCHIVE_STATE_DATA 4U
#define ARCHIVE_STATE_EOF 0x10U
#define ARCHIVE_STATE_CLOSED 0x20U
#define ARCHIVE_STATE_FATAL 0x8000U
#define ARCHIVE_STATE_ANY (0xFFFFU & ~ARCHIVE_STATE_FATAL)
struct archive_vtable {
int (*archive_close)(struct archive *);
int (*archive_free)(struct archive *);
int (*archive_write_header)(struct archive *,
struct archive_entry *);
int (*archive_write_finish_entry)(struct archive *);
ssize_t (*archive_write_data)(struct archive *,
const void *, size_t);
ssize_t (*archive_write_data_block)(struct archive *,
const void *, size_t, int64_t);
int (*archive_read_next_header)(struct archive *,
struct archive_entry **);
int (*archive_read_next_header2)(struct archive *,
struct archive_entry *);
int (*archive_read_data_block)(struct archive *,
const void **, size_t *, int64_t *);
int (*archive_filter_count)(struct archive *);
int64_t (*archive_filter_bytes)(struct archive *, int);
int (*archive_filter_code)(struct archive *, int);
const char * (*archive_filter_name)(struct archive *, int);
};
struct archive_string_conv;
struct archive {
/*
* The magic/state values are used to sanity-check the
* client's usage. If an API function is called at a
* ridiculous time, or the client passes us an invalid
* pointer, these values allow me to catch that.
*/
unsigned int magic;
unsigned int state;
/*
* Some public API functions depend on the "real" type of the
* archive object.
*/
struct archive_vtable *vtable;
int archive_format;
const char *archive_format_name;
int compression_code; /* Currently active compression. */
const char *compression_name;
/* Number of file entries processed. */
int file_count;
int archive_error_number;
const char *error;
struct archive_string error_string;
char *current_code;
unsigned current_codepage; /* Current ACP(ANSI CodePage). */
unsigned current_oemcp; /* Current OEMCP(OEM CodePage). */
struct archive_string_conv *sconv;
};
/* Check magic value and state; return(ARCHIVE_FATAL) if it isn't valid. */
int __archive_check_magic(struct archive *, unsigned int magic,
unsigned int state, const char *func);
#define archive_check_magic(a, expected_magic, allowed_states, function_name) \
do { \
int magic_test = __archive_check_magic((a), (expected_magic), \
(allowed_states), (function_name)); \
if (magic_test == ARCHIVE_FATAL) \
return ARCHIVE_FATAL; \
} while (0)
void __archive_errx(int retvalue, const char *msg) __LA_DEAD;
void __archive_ensure_cloexec_flag(int fd);
int __archive_mktemp(const char *tmpdir);
int __archive_clean(struct archive *);
#define err_combine(a,b) ((a) < (b) ? (a) : (b))
#if defined(__BORLANDC__) || (defined(_MSC_VER) && _MSC_VER <= 1300)
# define ARCHIVE_LITERAL_LL(x) x##i64
# define ARCHIVE_LITERAL_ULL(x) x##ui64
#else
# define ARCHIVE_LITERAL_LL(x) x##ll
# define ARCHIVE_LITERAL_ULL(x) x##ull
#endif
#endif

View file

@ -0,0 +1,709 @@
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas <matt@3am-software.com>.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Based on: NetBSD: rb.c,v 1.6 2010/04/30 13:58:09 joerg Exp
*/
#include "archive_platform.h"
#include <stddef.h>
#include "archive_rb.h"
/* Keep in sync with archive_rb.h */
#define RB_DIR_LEFT 0
#define RB_DIR_RIGHT 1
#define RB_DIR_OTHER 1
#define rb_left rb_nodes[RB_DIR_LEFT]
#define rb_right rb_nodes[RB_DIR_RIGHT]
#define RB_FLAG_POSITION 0x2
#define RB_FLAG_RED 0x1
#define RB_FLAG_MASK (RB_FLAG_POSITION|RB_FLAG_RED)
#define RB_FATHER(rb) \
((struct archive_rb_node *)((rb)->rb_info & ~RB_FLAG_MASK))
#define RB_SET_FATHER(rb, father) \
((void)((rb)->rb_info = (uintptr_t)(father)|((rb)->rb_info & RB_FLAG_MASK)))
#define RB_SENTINEL_P(rb) ((rb) == NULL)
#define RB_LEFT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_left)
#define RB_RIGHT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_right)
#define RB_FATHER_SENTINEL_P(rb) RB_SENTINEL_P(RB_FATHER((rb)))
#define RB_CHILDLESS_P(rb) \
(RB_SENTINEL_P(rb) || (RB_LEFT_SENTINEL_P(rb) && RB_RIGHT_SENTINEL_P(rb)))
#define RB_TWOCHILDREN_P(rb) \
(!RB_SENTINEL_P(rb) && !RB_LEFT_SENTINEL_P(rb) && !RB_RIGHT_SENTINEL_P(rb))
#define RB_POSITION(rb) \
(((rb)->rb_info & RB_FLAG_POSITION) ? RB_DIR_RIGHT : RB_DIR_LEFT)
#define RB_RIGHT_P(rb) (RB_POSITION(rb) == RB_DIR_RIGHT)
#define RB_LEFT_P(rb) (RB_POSITION(rb) == RB_DIR_LEFT)
#define RB_RED_P(rb) (!RB_SENTINEL_P(rb) && ((rb)->rb_info & RB_FLAG_RED) != 0)
#define RB_BLACK_P(rb) (RB_SENTINEL_P(rb) || ((rb)->rb_info & RB_FLAG_RED) == 0)
#define RB_MARK_RED(rb) ((void)((rb)->rb_info |= RB_FLAG_RED))
#define RB_MARK_BLACK(rb) ((void)((rb)->rb_info &= ~RB_FLAG_RED))
#define RB_INVERT_COLOR(rb) ((void)((rb)->rb_info ^= RB_FLAG_RED))
#define RB_ROOT_P(rbt, rb) ((rbt)->rbt_root == (rb))
#define RB_SET_POSITION(rb, position) \
((void)((position) ? ((rb)->rb_info |= RB_FLAG_POSITION) : \
((rb)->rb_info &= ~RB_FLAG_POSITION)))
#define RB_ZERO_PROPERTIES(rb) ((void)((rb)->rb_info &= ~RB_FLAG_MASK))
#define RB_COPY_PROPERTIES(dst, src) \
((void)((dst)->rb_info ^= ((dst)->rb_info ^ (src)->rb_info) & RB_FLAG_MASK))
#define RB_SWAP_PROPERTIES(a, b) do { \
uintptr_t xorinfo = ((a)->rb_info ^ (b)->rb_info) & RB_FLAG_MASK; \
(a)->rb_info ^= xorinfo; \
(b)->rb_info ^= xorinfo; \
} while (/*CONSTCOND*/ 0)
static void __archive_rb_tree_insert_rebalance(struct archive_rb_tree *,
struct archive_rb_node *);
static void __archive_rb_tree_removal_rebalance(struct archive_rb_tree *,
struct archive_rb_node *, unsigned int);
#define RB_SENTINEL_NODE NULL
#define T 1
#define F 0
void
__archive_rb_tree_init(struct archive_rb_tree *rbt,
const struct archive_rb_tree_ops *ops)
{
rbt->rbt_ops = ops;
*((struct archive_rb_node **)&rbt->rbt_root) = RB_SENTINEL_NODE;
}
struct archive_rb_node *
__archive_rb_tree_find_node(struct archive_rb_tree *rbt, const void *key)
{
archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key;
struct archive_rb_node *parent = rbt->rbt_root;
while (!RB_SENTINEL_P(parent)) {
const signed int diff = (*compare_key)(parent, key);
if (diff == 0)
return parent;
parent = parent->rb_nodes[diff > 0];
}
return NULL;
}
struct archive_rb_node *
__archive_rb_tree_find_node_geq(struct archive_rb_tree *rbt, const void *key)
{
archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key;
struct archive_rb_node *parent = rbt->rbt_root;
struct archive_rb_node *last = NULL;
while (!RB_SENTINEL_P(parent)) {
const signed int diff = (*compare_key)(parent, key);
if (diff == 0)
return parent;
if (diff < 0)
last = parent;
parent = parent->rb_nodes[diff > 0];
}
return last;
}
struct archive_rb_node *
__archive_rb_tree_find_node_leq(struct archive_rb_tree *rbt, const void *key)
{
archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key;
struct archive_rb_node *parent = rbt->rbt_root;
struct archive_rb_node *last = NULL;
while (!RB_SENTINEL_P(parent)) {
const signed int diff = (*compare_key)(parent, key);
if (diff == 0)
return parent;
if (diff > 0)
last = parent;
parent = parent->rb_nodes[diff > 0];
}
return last;
}
int
__archive_rb_tree_insert_node(struct archive_rb_tree *rbt,
struct archive_rb_node *self)
{
archive_rbto_compare_nodes_fn compare_nodes = rbt->rbt_ops->rbto_compare_nodes;
struct archive_rb_node *parent, *tmp;
unsigned int position;
int rebalance;
tmp = rbt->rbt_root;
/*
* This is a hack. Because rbt->rbt_root is just a
* struct archive_rb_node *, just like rb_node->rb_nodes[RB_DIR_LEFT],
* we can use this fact to avoid a lot of tests for root and know
* that even at root, updating
* RB_FATHER(rb_node)->rb_nodes[RB_POSITION(rb_node)] will
* update rbt->rbt_root.
*/
parent = (struct archive_rb_node *)(void *)&rbt->rbt_root;
position = RB_DIR_LEFT;
/*
* Find out where to place this new leaf.
*/
while (!RB_SENTINEL_P(tmp)) {
const signed int diff = (*compare_nodes)(tmp, self);
if (diff == 0) {
/*
* Node already exists; don't insert.
*/
return F;
}
parent = tmp;
position = (diff > 0);
tmp = parent->rb_nodes[position];
}
/*
* Initialize the node and insert as a leaf into the tree.
*/
RB_SET_FATHER(self, parent);
RB_SET_POSITION(self, position);
if (parent == (struct archive_rb_node *)(void *)&rbt->rbt_root) {
RB_MARK_BLACK(self); /* root is always black */
rebalance = F;
} else {
/*
* All new nodes are colored red. We only need to rebalance
* if our parent is also red.
*/
RB_MARK_RED(self);
rebalance = RB_RED_P(parent);
}
self->rb_left = parent->rb_nodes[position];
self->rb_right = parent->rb_nodes[position];
parent->rb_nodes[position] = self;
/*
* Rebalance tree after insertion
*/
if (rebalance)
__archive_rb_tree_insert_rebalance(rbt, self);
return T;
}
/*
* Swap the location and colors of 'self' and its child @ which. The child
* can not be a sentinel node. This is our rotation function. However,
* since it preserves coloring, it great simplifies both insertion and
* removal since rotation almost always involves the exchanging of colors
* as a separate step.
*/
/*ARGSUSED*/
static void
__archive_rb_tree_reparent_nodes(
struct archive_rb_node *old_father, const unsigned int which)
{
const unsigned int other = which ^ RB_DIR_OTHER;
struct archive_rb_node * const grandpa = RB_FATHER(old_father);
struct archive_rb_node * const old_child = old_father->rb_nodes[which];
struct archive_rb_node * const new_father = old_child;
struct archive_rb_node * const new_child = old_father;
if (new_father == NULL)
return;
/*
* Exchange descendant linkages.
*/
grandpa->rb_nodes[RB_POSITION(old_father)] = new_father;
new_child->rb_nodes[which] = old_child->rb_nodes[other];
new_father->rb_nodes[other] = new_child;
/*
* Update ancestor linkages
*/
RB_SET_FATHER(new_father, grandpa);
RB_SET_FATHER(new_child, new_father);
/*
* Exchange properties between new_father and new_child. The only
* change is that new_child's position is now on the other side.
*/
RB_SWAP_PROPERTIES(new_father, new_child);
RB_SET_POSITION(new_child, other);
/*
* Make sure to reparent the new child to ourself.
*/
if (!RB_SENTINEL_P(new_child->rb_nodes[which])) {
RB_SET_FATHER(new_child->rb_nodes[which], new_child);
RB_SET_POSITION(new_child->rb_nodes[which], which);
}
}
static void
__archive_rb_tree_insert_rebalance(struct archive_rb_tree *rbt,
struct archive_rb_node *self)
{
struct archive_rb_node * father = RB_FATHER(self);
struct archive_rb_node * grandpa;
struct archive_rb_node * uncle;
unsigned int which;
unsigned int other;
for (;;) {
/*
* We are red and our parent is red, therefore we must have a
* grandfather and he must be black.
*/
grandpa = RB_FATHER(father);
which = (father == grandpa->rb_right);
other = which ^ RB_DIR_OTHER;
uncle = grandpa->rb_nodes[other];
if (RB_BLACK_P(uncle))
break;
/*
* Case 1: our uncle is red
* Simply invert the colors of our parent and
* uncle and make our grandparent red. And
* then solve the problem up at his level.
*/
RB_MARK_BLACK(uncle);
RB_MARK_BLACK(father);
if (RB_ROOT_P(rbt, grandpa)) {
/*
* If our grandpa is root, don't bother
* setting him to red, just return.
*/
return;
}
RB_MARK_RED(grandpa);
self = grandpa;
father = RB_FATHER(self);
if (RB_BLACK_P(father)) {
/*
* If our greatgrandpa is black, we're done.
*/
return;
}
}
/*
* Case 2&3: our uncle is black.
*/
if (self == father->rb_nodes[other]) {
/*
* Case 2: we are on the same side as our uncle
* Swap ourselves with our parent so this case
* becomes case 3. Basically our parent becomes our
* child.
*/
__archive_rb_tree_reparent_nodes(father, other);
}
/*
* Case 3: we are opposite a child of a black uncle.
* Swap our parent and grandparent. Since our grandfather
* is black, our father will become black and our new sibling
* (former grandparent) will become red.
*/
__archive_rb_tree_reparent_nodes(grandpa, which);
/*
* Final step: Set the root to black.
*/
RB_MARK_BLACK(rbt->rbt_root);
}
static void
__archive_rb_tree_prune_node(struct archive_rb_tree *rbt,
struct archive_rb_node *self, int rebalance)
{
const unsigned int which = RB_POSITION(self);
struct archive_rb_node *father = RB_FATHER(self);
/*
* Since we are childless, we know that self->rb_left is pointing
* to the sentinel node.
*/
father->rb_nodes[which] = self->rb_left;
/*
* Rebalance if requested.
*/
if (rebalance)
__archive_rb_tree_removal_rebalance(rbt, father, which);
}
/*
* When deleting an interior node
*/
static void
__archive_rb_tree_swap_prune_and_rebalance(struct archive_rb_tree *rbt,
struct archive_rb_node *self, struct archive_rb_node *standin)
{
const unsigned int standin_which = RB_POSITION(standin);
unsigned int standin_other = standin_which ^ RB_DIR_OTHER;
struct archive_rb_node *standin_son;
struct archive_rb_node *standin_father = RB_FATHER(standin);
int rebalance = RB_BLACK_P(standin);
if (standin_father == self) {
/*
* As a child of self, any children would be opposite of
* our parent.
*/
standin_son = standin->rb_nodes[standin_which];
} else {
/*
* Since we aren't a child of self, any children would be
* on the same side as our parent.
*/
standin_son = standin->rb_nodes[standin_other];
}
if (RB_RED_P(standin_son)) {
/*
* We know we have a red child so if we flip it to black
* we don't have to rebalance.
*/
RB_MARK_BLACK(standin_son);
rebalance = F;
if (standin_father != self) {
/*
* Change the son's parentage to point to his grandpa.
*/
RB_SET_FATHER(standin_son, standin_father);
RB_SET_POSITION(standin_son, standin_which);
}
}
if (standin_father == self) {
/*
* If we are about to delete the standin's father, then when
* we call rebalance, we need to use ourselves as our father.
* Otherwise remember our original father. Also, since we are
* our standin's father we only need to reparent the standin's
* brother.
*
* | R --> S |
* | Q S --> Q T |
* | t --> |
*
* Have our son/standin adopt his brother as his new son.
*/
standin_father = standin;
} else {
/*
* | R --> S . |
* | / \ | T --> / \ | / |
* | ..... | S --> ..... | T |
*
* Sever standin's connection to his father.
*/
standin_father->rb_nodes[standin_which] = standin_son;
/*
* Adopt the far son.
*/
standin->rb_nodes[standin_other] = self->rb_nodes[standin_other];
RB_SET_FATHER(standin->rb_nodes[standin_other], standin);
/*
* Use standin_other because we need to preserve standin_which
* for the removal_rebalance.
*/
standin_other = standin_which;
}
/*
* Move the only remaining son to our standin. If our standin is our
* son, this will be the only son needed to be moved.
*/
standin->rb_nodes[standin_other] = self->rb_nodes[standin_other];
RB_SET_FATHER(standin->rb_nodes[standin_other], standin);
/*
* Now copy the result of self to standin and then replace
* self with standin in the tree.
*/
RB_COPY_PROPERTIES(standin, self);
RB_SET_FATHER(standin, RB_FATHER(self));
RB_FATHER(standin)->rb_nodes[RB_POSITION(standin)] = standin;
if (rebalance)
__archive_rb_tree_removal_rebalance(rbt, standin_father, standin_which);
}
/*
* We could do this by doing
* __archive_rb_tree_node_swap(rbt, self, which);
* __archive_rb_tree_prune_node(rbt, self, F);
*
* But it's more efficient to just evaluate and recolor the child.
*/
static void
__archive_rb_tree_prune_blackred_branch(
struct archive_rb_node *self, unsigned int which)
{
struct archive_rb_node *father = RB_FATHER(self);
struct archive_rb_node *son = self->rb_nodes[which];
/*
* Remove ourselves from the tree and give our former child our
* properties (position, color, root).
*/
RB_COPY_PROPERTIES(son, self);
father->rb_nodes[RB_POSITION(son)] = son;
RB_SET_FATHER(son, father);
}
/*
*
*/
void
__archive_rb_tree_remove_node(struct archive_rb_tree *rbt,
struct archive_rb_node *self)
{
struct archive_rb_node *standin;
unsigned int which;
/*
* In the following diagrams, we (the node to be removed) are S. Red
* nodes are lowercase. T could be either red or black.
*
* Remember the major axiom of the red-black tree: the number of
* black nodes from the root to each leaf is constant across all
* leaves, only the number of red nodes varies.
*
* Thus removing a red leaf doesn't require any other changes to a
* red-black tree. So if we must remove a node, attempt to rearrange
* the tree so we can remove a red node.
*
* The simplest case is a childless red node or a childless root node:
*
* | T --> T | or | R --> * |
* | s --> * |
*/
if (RB_CHILDLESS_P(self)) {
const int rebalance = RB_BLACK_P(self) && !RB_ROOT_P(rbt, self);
__archive_rb_tree_prune_node(rbt, self, rebalance);
return;
}
if (!RB_TWOCHILDREN_P(self)) {
/*
* The next simplest case is the node we are deleting is
* black and has one red child.
*
* | T --> T --> T |
* | S --> R --> R |
* | r --> s --> * |
*/
which = RB_LEFT_SENTINEL_P(self) ? RB_DIR_RIGHT : RB_DIR_LEFT;
__archive_rb_tree_prune_blackred_branch(self, which);
return;
}
/*
* We invert these because we prefer to remove from the inside of
* the tree.
*/
which = RB_POSITION(self) ^ RB_DIR_OTHER;
/*
* Let's find the node closes to us opposite of our parent
* Now swap it with ourself, "prune" it, and rebalance, if needed.
*/
standin = __archive_rb_tree_iterate(rbt, self, which);
__archive_rb_tree_swap_prune_and_rebalance(rbt, self, standin);
}
static void
__archive_rb_tree_removal_rebalance(struct archive_rb_tree *rbt,
struct archive_rb_node *parent, unsigned int which)
{
while (RB_BLACK_P(parent->rb_nodes[which])) {
unsigned int other = which ^ RB_DIR_OTHER;
struct archive_rb_node *brother = parent->rb_nodes[other];
if (brother == NULL)
return;/* The tree may be broken. */
/*
* For cases 1, 2a, and 2b, our brother's children must
* be black and our father must be black
*/
if (RB_BLACK_P(parent)
&& RB_BLACK_P(brother->rb_left)
&& RB_BLACK_P(brother->rb_right)) {
if (RB_RED_P(brother)) {
/*
* Case 1: Our brother is red, swap its
* position (and colors) with our parent.
* This should now be case 2b (unless C or E
* has a red child which is case 3; thus no
* explicit branch to case 2b).
*
* B -> D
* A d -> b E
* C E -> A C
*/
__archive_rb_tree_reparent_nodes(parent, other);
brother = parent->rb_nodes[other];
if (brother == NULL)
return;/* The tree may be broken. */
} else {
/*
* Both our parent and brother are black.
* Change our brother to red, advance up rank
* and go through the loop again.
*
* B -> *B
* *A D -> A d
* C E -> C E
*/
RB_MARK_RED(brother);
if (RB_ROOT_P(rbt, parent))
return; /* root == parent == black */
which = RB_POSITION(parent);
parent = RB_FATHER(parent);
continue;
}
}
/*
* Avoid an else here so that case 2a above can hit either
* case 2b, 3, or 4.
*/
if (RB_RED_P(parent)
&& RB_BLACK_P(brother)
&& RB_BLACK_P(brother->rb_left)
&& RB_BLACK_P(brother->rb_right)) {
/*
* We are black, our father is red, our brother and
* both nephews are black. Simply invert/exchange the
* colors of our father and brother (to black and red
* respectively).
*
* | f --> F |
* | * B --> * b |
* | N N --> N N |
*/
RB_MARK_BLACK(parent);
RB_MARK_RED(brother);
break; /* We're done! */
} else {
/*
* Our brother must be black and have at least one
* red child (it may have two).
*/
if (RB_BLACK_P(brother->rb_nodes[other])) {
/*
* Case 3: our brother is black, our near
* nephew is red, and our far nephew is black.
* Swap our brother with our near nephew.
* This result in a tree that matches case 4.
* (Our father could be red or black).
*
* | F --> F |
* | x B --> x B |
* | n --> n |
*/
__archive_rb_tree_reparent_nodes(brother, which);
brother = parent->rb_nodes[other];
}
/*
* Case 4: our brother is black and our far nephew
* is red. Swap our father and brother locations and
* change our far nephew to black. (these can be
* done in either order so we change the color first).
* The result is a valid red-black tree and is a
* terminal case. (again we don't care about the
* father's color)
*
* If the father is red, we will get a red-black-black
* tree:
* | f -> f --> b |
* | B -> B --> F N |
* | n -> N --> |
*
* If the father is black, we will get an all black
* tree:
* | F -> F --> B |
* | B -> B --> F N |
* | n -> N --> |
*
* If we had two red nephews, then after the swap,
* our former father would have a red grandson.
*/
if (brother->rb_nodes[other] == NULL)
return;/* The tree may be broken. */
RB_MARK_BLACK(brother->rb_nodes[other]);
__archive_rb_tree_reparent_nodes(parent, other);
break; /* We're done! */
}
}
}
struct archive_rb_node *
__archive_rb_tree_iterate(struct archive_rb_tree *rbt,
struct archive_rb_node *self, const unsigned int direction)
{
const unsigned int other = direction ^ RB_DIR_OTHER;
if (self == NULL) {
self = rbt->rbt_root;
if (RB_SENTINEL_P(self))
return NULL;
while (!RB_SENTINEL_P(self->rb_nodes[direction]))
self = self->rb_nodes[direction];
return self;
}
/*
* We can't go any further in this direction. We proceed up in the
* opposite direction until our parent is in direction we want to go.
*/
if (RB_SENTINEL_P(self->rb_nodes[direction])) {
while (!RB_ROOT_P(rbt, self)) {
if (other == (unsigned int)RB_POSITION(self))
return RB_FATHER(self);
self = RB_FATHER(self);
}
return NULL;
}
/*
* Advance down one in current direction and go down as far as possible
* in the opposite direction.
*/
self = self->rb_nodes[direction];
while (!RB_SENTINEL_P(self->rb_nodes[other]))
self = self->rb_nodes[other];
return self;
}

View file

@ -0,0 +1,100 @@
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas <matt@3am-software.com>.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Based on NetBSD: rb.h,v 1.13 2009/08/16 10:57:01 yamt Exp
*/
#ifndef ARCHIVE_RB_H_
#define ARCHIVE_RB_H_
struct archive_rb_node {
struct archive_rb_node *rb_nodes[2];
/*
* rb_info contains the two flags and the parent back pointer.
* We put the two flags in the low two bits since we know that
* rb_node will have an alignment of 4 or 8 bytes.
*/
uintptr_t rb_info;
};
#define ARCHIVE_RB_DIR_LEFT 0
#define ARCHIVE_RB_DIR_RIGHT 1
#define ARCHIVE_RB_TREE_MIN(T) \
__archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_LEFT)
#define ARCHIVE_RB_TREE_MAX(T) \
__archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_RIGHT)
#define ARCHIVE_RB_TREE_FOREACH(N, T) \
for ((N) = ARCHIVE_RB_TREE_MIN(T); (N); \
(N) = __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_RIGHT))
#define ARCHIVE_RB_TREE_FOREACH_REVERSE(N, T) \
for ((N) = ARCHIVE_RB_TREE_MAX(T); (N); \
(N) = __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_LEFT))
/*
* archive_rbto_compare_nodes_fn:
* return a positive value if the first node < the second node.
* return a negative value if the first node > the second node.
* return 0 if they are considered same.
*
* archive_rbto_compare_key_fn:
* return a positive value if the node < the key.
* return a negative value if the node > the key.
* return 0 if they are considered same.
*/
typedef signed int (*const archive_rbto_compare_nodes_fn)(const struct archive_rb_node *,
const struct archive_rb_node *);
typedef signed int (*const archive_rbto_compare_key_fn)(const struct archive_rb_node *,
const void *);
struct archive_rb_tree_ops {
archive_rbto_compare_nodes_fn rbto_compare_nodes;
archive_rbto_compare_key_fn rbto_compare_key;
};
struct archive_rb_tree {
struct archive_rb_node *rbt_root;
const struct archive_rb_tree_ops *rbt_ops;
};
void __archive_rb_tree_init(struct archive_rb_tree *,
const struct archive_rb_tree_ops *);
int __archive_rb_tree_insert_node(struct archive_rb_tree *,
struct archive_rb_node *);
struct archive_rb_node *
__archive_rb_tree_find_node(struct archive_rb_tree *, const void *);
struct archive_rb_node *
__archive_rb_tree_find_node_geq(struct archive_rb_tree *, const void *);
struct archive_rb_node *
__archive_rb_tree_find_node_leq(struct archive_rb_tree *, const void *);
void __archive_rb_tree_remove_node(struct archive_rb_tree *, struct archive_rb_node *);
struct archive_rb_node *
__archive_rb_tree_iterate(struct archive_rb_tree *,
struct archive_rb_node *, const unsigned int);
#endif /* ARCHIVE_RB_H_*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,198 @@
/*-
* Copyright (c) 2003-2012 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include "archive.h"
#include "archive_private.h"
#include "archive_read_private.h"
int
archive_read_append_filter(struct archive *_a, int code)
{
int r1, r2, number_bidders, i;
char str[20];
struct archive_read_filter_bidder *bidder;
struct archive_read_filter *filter;
struct archive_read *a = (struct archive_read *)_a;
r1 = r2 = (ARCHIVE_OK);
switch (code)
{
case ARCHIVE_FILTER_NONE:
/* No filter to add, so do nothing.
* NOTE: An initial "NONE" type filter is always set at the end of the
* filter chain.
*/
r1 = (ARCHIVE_OK);
break;
case ARCHIVE_FILTER_GZIP:
strcpy(str, "gzip");
r1 = archive_read_support_filter_gzip(_a);
break;
case ARCHIVE_FILTER_BZIP2:
strcpy(str, "bzip2");
r1 = archive_read_support_filter_bzip2(_a);
break;
case ARCHIVE_FILTER_COMPRESS:
strcpy(str, "compress (.Z)");
r1 = archive_read_support_filter_compress(_a);
break;
case ARCHIVE_FILTER_PROGRAM:
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
"Cannot append program filter using archive_read_append_filter");
return (ARCHIVE_FATAL);
case ARCHIVE_FILTER_LZMA:
strcpy(str, "lzma");
r1 = archive_read_support_filter_lzma(_a);
break;
case ARCHIVE_FILTER_XZ:
strcpy(str, "xz");
r1 = archive_read_support_filter_xz(_a);
break;
case ARCHIVE_FILTER_UU:
strcpy(str, "uu");
r1 = archive_read_support_filter_uu(_a);
break;
case ARCHIVE_FILTER_RPM:
strcpy(str, "rpm");
r1 = archive_read_support_filter_rpm(_a);
break;
case ARCHIVE_FILTER_LZIP:
strcpy(str, "lzip");
r1 = archive_read_support_filter_lzip(_a);
break;
case ARCHIVE_FILTER_LRZIP:
strcpy(str, "lrzip");
r1 = archive_read_support_filter_lrzip(_a);
break;
default:
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
"Invalid filter code specified");
return (ARCHIVE_FATAL);
}
if (code != ARCHIVE_FILTER_NONE)
{
number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
bidder = a->bidders;
for (i = 0; i < number_bidders; i++, bidder++)
{
if (!bidder->name || !strcmp(bidder->name, str))
break;
}
if (!bidder->name || strcmp(bidder->name, str))
{
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
"Internal error: Unable to append filter");
return (ARCHIVE_FATAL);
}
filter
= (struct archive_read_filter *)calloc(1, sizeof(*filter));
if (filter == NULL)
{
archive_set_error(&a->archive, ENOMEM, "Out of memory");
return (ARCHIVE_FATAL);
}
filter->bidder = bidder;
filter->archive = a;
filter->upstream = a->filter;
a->filter = filter;
r2 = (bidder->init)(a->filter);
if (r2 != ARCHIVE_OK) {
__archive_read_close_filters(a);
__archive_read_free_filters(a);
return (ARCHIVE_FATAL);
}
}
a->bypass_filter_bidding = 1;
return (r1 < r2) ? r1 : r2;
}
int
archive_read_append_filter_program(struct archive *_a, const char *cmd)
{
return (archive_read_append_filter_program_signature(_a, cmd, NULL, 0));
}
int
archive_read_append_filter_program_signature(struct archive *_a,
const char *cmd, const void *signature, size_t signature_len)
{
int r, number_bidders, i;
struct archive_read_filter_bidder *bidder;
struct archive_read_filter *filter;
struct archive_read *a = (struct archive_read *)_a;
if (archive_read_support_filter_program_signature(_a, cmd, signature,
signature_len) != (ARCHIVE_OK))
return (ARCHIVE_FATAL);
number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
bidder = a->bidders;
for (i = 0; i < number_bidders; i++, bidder++)
{
/* Program bidder name set to filter name after initialization */
if (bidder->data && !bidder->name)
break;
}
if (!bidder->data)
{
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
"Internal error: Unable to append program filter");
return (ARCHIVE_FATAL);
}
filter
= (struct archive_read_filter *)calloc(1, sizeof(*filter));
if (filter == NULL)
{
archive_set_error(&a->archive, ENOMEM, "Out of memory");
return (ARCHIVE_FATAL);
}
filter->bidder = bidder;
filter->archive = a;
filter->upstream = a->filter;
a->filter = filter;
r = (bidder->init)(a->filter);
if (r != ARCHIVE_OK) {
__archive_read_close_filters(a);
__archive_read_free_filters(a);
return (ARCHIVE_FATAL);
}
bidder->name = a->filter->name;
a->bypass_filter_bidding = 1;
return r;
}

View file

@ -0,0 +1,139 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_data_into_fd.c,v 1.16 2008/05/23 05:01:29 cperciva Exp $");
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "archive.h"
#include "archive_private.h"
/* Maximum amount of data to write at one time. */
#define MAX_WRITE (1024 * 1024)
/*
* This implementation minimizes copying of data and is sparse-file aware.
*/
static int
pad_to(struct archive *a, int fd, int can_lseek,
size_t nulls_size, const char *nulls,
int64_t target_offset, int64_t actual_offset)
{
size_t to_write;
ssize_t bytes_written;
if (can_lseek) {
actual_offset = lseek(fd,
target_offset - actual_offset, SEEK_CUR);
if (actual_offset != target_offset) {
archive_set_error(a, errno, "Seek error");
return (ARCHIVE_FATAL);
}
return (ARCHIVE_OK);
}
while (target_offset > actual_offset) {
to_write = nulls_size;
if (target_offset < actual_offset + (int64_t)nulls_size)
to_write = (size_t)(target_offset - actual_offset);
bytes_written = write(fd, nulls, to_write);
if (bytes_written < 0) {
archive_set_error(a, errno, "Write error");
return (ARCHIVE_FATAL);
}
actual_offset += bytes_written;
}
return (ARCHIVE_OK);
}
int
archive_read_data_into_fd(struct archive *a, int fd)
{
struct stat st;
int r, r2;
const void *buff;
size_t size, bytes_to_write;
ssize_t bytes_written;
int64_t target_offset;
int64_t actual_offset = 0;
int can_lseek;
char *nulls = NULL;
size_t nulls_size = 16384;
archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
"archive_read_data_into_fd");
can_lseek = (fstat(fd, &st) == 0) && S_ISREG(st.st_mode);
if (!can_lseek)
nulls = calloc(1, nulls_size);
while ((r = archive_read_data_block(a, &buff, &size, &target_offset)) ==
ARCHIVE_OK) {
const char *p = buff;
if (target_offset > actual_offset) {
r = pad_to(a, fd, can_lseek, nulls_size, nulls,
target_offset, actual_offset);
if (r != ARCHIVE_OK)
break;
actual_offset = target_offset;
}
while (size > 0) {
bytes_to_write = size;
if (bytes_to_write > MAX_WRITE)
bytes_to_write = MAX_WRITE;
bytes_written = write(fd, p, bytes_to_write);
if (bytes_written < 0) {
archive_set_error(a, errno, "Write error");
r = ARCHIVE_FATAL;
goto cleanup;
}
actual_offset += bytes_written;
p += bytes_written;
size -= bytes_written;
}
}
if (r == ARCHIVE_EOF && target_offset > actual_offset) {
r2 = pad_to(a, fd, can_lseek, nulls_size, nulls,
target_offset, actual_offset);
if (r2 != ARCHIVE_OK)
r = r2;
}
cleanup:
free(nulls);
if (r != ARCHIVE_EOF)
return (r);
return (ARCHIVE_OK);
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,92 @@
/*-
* Copyright (c) 2003-2009 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: head/lib/libarchive/archive_read_disk_private.h 201105 2009-12-28 03:20:54Z kientzle $
*/
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
#define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
struct tree;
struct archive_entry;
struct archive_read_disk {
struct archive archive;
/*
* Symlink mode is one of 'L'ogical, 'P'hysical, or 'H'ybrid,
* following an old BSD convention. 'L' follows all symlinks,
* 'P' follows none, 'H' follows symlinks only for the first
* item.
*/
char symlink_mode;
/*
* Since symlink interaction changes, we need to track whether
* we're following symlinks for the current item. 'L' mode above
* sets this true, 'P' sets it false, 'H' changes it as we traverse.
*/
char follow_symlinks; /* Either 'L' or 'P'. */
/* Directory traversals. */
struct tree *tree;
int (*open_on_current_dir)(struct tree*, const char *, int);
int (*tree_current_dir_fd)(struct tree*);
int (*tree_enter_working_dir)(struct tree*);
/* Set 1 if users request to restore atime . */
int restore_time;
/* Set 1 if users request to honor nodump flag . */
int honor_nodump;
/* Set 1 if users request to enable mac copyfile. */
int enable_copyfile;
/* Set 1 if users request to traverse mount points. */
int traverse_mount_points;
const char * (*lookup_gname)(void *private, int64_t gid);
void (*cleanup_gname)(void *private);
void *lookup_gname_data;
const char * (*lookup_uname)(void *private, int64_t uid);
void (*cleanup_uname)(void *private);
void *lookup_uname_data;
int (*metadata_filter_func)(struct archive *, void *,
struct archive_entry *);
void *metadata_filter_data;
/* ARCHIVE_MATCH object. */
struct archive *matching;
/* Callback function, this will be invoked when ARCHIVE_MATCH
* archive_match_*_excluded_ae return true. */
void (*excluded_cb_func)(struct archive *, void *,
struct archive_entry *);
void *excluded_cb_data;
};
#endif

View file

@ -0,0 +1,311 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_set_standard_lookup.c 201109 2009-12-28 03:30:31Z kientzle $");
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_GRP_H
#include <grp.h>
#endif
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include "archive.h"
#if defined(_WIN32) && !defined(__CYGWIN__)
int
archive_read_disk_set_standard_lookup(struct archive *a)
{
archive_set_error(a, -1, "Standard lookups not available on Windows");
return (ARCHIVE_FATAL);
}
#else /* ! (_WIN32 && !__CYGWIN__) */
#define name_cache_size 127
static const char * const NO_NAME = "(noname)";
struct name_cache {
struct archive *archive;
char *buff;
size_t buff_size;
int probes;
int hits;
size_t size;
struct {
id_t id;
const char *name;
} cache[name_cache_size];
};
static const char * lookup_gname(void *, int64_t);
static const char * lookup_uname(void *, int64_t);
static void cleanup(void *);
static const char * lookup_gname_helper(struct name_cache *, id_t gid);
static const char * lookup_uname_helper(struct name_cache *, id_t uid);
/*
* Installs functions that use getpwuid()/getgrgid()---along with
* a simple cache to accelerate such lookups---into the archive_read_disk
* object. This is in a separate file because getpwuid()/getgrgid()
* can pull in a LOT of library code (including NIS/LDAP functions, which
* pull in DNS resolveers, etc). This can easily top 500kB, which makes
* it inappropriate for some space-constrained applications.
*
* Applications that are size-sensitive may want to just use the
* real default functions (defined in archive_read_disk.c) that just
* use the uid/gid without the lookup. Or define your own custom functions
* if you prefer.
*/
int
archive_read_disk_set_standard_lookup(struct archive *a)
{
struct name_cache *ucache = malloc(sizeof(struct name_cache));
struct name_cache *gcache = malloc(sizeof(struct name_cache));
if (ucache == NULL || gcache == NULL) {
archive_set_error(a, ENOMEM,
"Can't allocate uname/gname lookup cache");
free(ucache);
free(gcache);
return (ARCHIVE_FATAL);
}
memset(ucache, 0, sizeof(*ucache));
ucache->archive = a;
ucache->size = name_cache_size;
memset(gcache, 0, sizeof(*gcache));
gcache->archive = a;
gcache->size = name_cache_size;
archive_read_disk_set_gname_lookup(a, gcache, lookup_gname, cleanup);
archive_read_disk_set_uname_lookup(a, ucache, lookup_uname, cleanup);
return (ARCHIVE_OK);
}
static void
cleanup(void *data)
{
struct name_cache *cache = (struct name_cache *)data;
size_t i;
if (cache != NULL) {
for (i = 0; i < cache->size; i++) {
if (cache->cache[i].name != NULL &&
cache->cache[i].name != NO_NAME)
free((void *)(uintptr_t)cache->cache[i].name);
}
free(cache->buff);
free(cache);
}
}
/*
* Lookup uid/gid from uname/gname, return NULL if no match.
*/
static const char *
lookup_name(struct name_cache *cache,
const char * (*lookup_fn)(struct name_cache *, id_t), id_t id)
{
const char *name;
int slot;
cache->probes++;
slot = id % cache->size;
if (cache->cache[slot].name != NULL) {
if (cache->cache[slot].id == id) {
cache->hits++;
if (cache->cache[slot].name == NO_NAME)
return (NULL);
return (cache->cache[slot].name);
}
if (cache->cache[slot].name != NO_NAME)
free((void *)(uintptr_t)cache->cache[slot].name);
cache->cache[slot].name = NULL;
}
name = (lookup_fn)(cache, id);
if (name == NULL) {
/* Cache and return the negative response. */
cache->cache[slot].name = NO_NAME;
cache->cache[slot].id = id;
return (NULL);
}
cache->cache[slot].name = name;
cache->cache[slot].id = id;
return (cache->cache[slot].name);
}
static const char *
lookup_uname(void *data, int64_t uid)
{
struct name_cache *uname_cache = (struct name_cache *)data;
return (lookup_name(uname_cache,
&lookup_uname_helper, (id_t)uid));
}
#if HAVE_GETPWUID_R
static const char *
lookup_uname_helper(struct name_cache *cache, id_t id)
{
struct passwd pwent, *result;
char * nbuff;
size_t nbuff_size;
int r;
if (cache->buff_size == 0) {
cache->buff_size = 256;
cache->buff = malloc(cache->buff_size);
}
if (cache->buff == NULL)
return (NULL);
for (;;) {
result = &pwent; /* Old getpwuid_r ignores last arg. */
r = getpwuid_r((uid_t)id, &pwent,
cache->buff, cache->buff_size, &result);
if (r == 0)
break;
if (r != ERANGE)
break;
/* ERANGE means our buffer was too small, but POSIX
* doesn't tell us how big the buffer should be, so
* we just double it and try again. Because the buffer
* is kept around in the cache object, we shouldn't
* have to do this very often. */
nbuff_size = cache->buff_size * 2;
nbuff = realloc(cache->buff, nbuff_size);
if (nbuff == NULL)
break;
cache->buff = nbuff;
cache->buff_size = nbuff_size;
}
if (r != 0) {
archive_set_error(cache->archive, errno,
"Can't lookup user for id %d", (int)id);
return (NULL);
}
if (result == NULL)
return (NULL);
return strdup(result->pw_name);
}
#else
static const char *
lookup_uname_helper(struct name_cache *cache, id_t id)
{
struct passwd *result;
result = getpwuid((uid_t)id);
if (result == NULL)
return (NULL);
return strdup(result->pw_name);
}
#endif
static const char *
lookup_gname(void *data, int64_t gid)
{
struct name_cache *gname_cache = (struct name_cache *)data;
return (lookup_name(gname_cache,
&lookup_gname_helper, (id_t)gid));
}
#if HAVE_GETGRGID_R
static const char *
lookup_gname_helper(struct name_cache *cache, id_t id)
{
struct group grent, *result;
char * nbuff;
size_t nbuff_size;
int r;
if (cache->buff_size == 0) {
cache->buff_size = 256;
cache->buff = malloc(cache->buff_size);
}
if (cache->buff == NULL)
return (NULL);
for (;;) {
result = &grent; /* Old getgrgid_r ignores last arg. */
r = getgrgid_r((gid_t)id, &grent,
cache->buff, cache->buff_size, &result);
if (r == 0)
break;
if (r != ERANGE)
break;
/* ERANGE means our buffer was too small, but POSIX
* doesn't tell us how big the buffer should be, so
* we just double it and try again. */
nbuff_size = cache->buff_size * 2;
nbuff = realloc(cache->buff, nbuff_size);
if (nbuff == NULL)
break;
cache->buff = nbuff;
cache->buff_size = nbuff_size;
}
if (r != 0) {
archive_set_error(cache->archive, errno,
"Can't lookup group for id %d", (int)id);
return (NULL);
}
if (result == NULL)
return (NULL);
return strdup(result->gr_name);
}
#else
static const char *
lookup_gname_helper(struct name_cache *cache, id_t id)
{
struct group *result;
result = getgrgid((gid_t)id);
if (result == NULL)
return (NULL);
return strdup(result->gr_name);
}
#endif
#endif /* ! (_WIN32 && !__CYGWIN__) */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,183 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_extract.c,v 1.61 2008/05/26 17:00:22 kientzle Exp $");
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include "archive.h"
#include "archive_entry.h"
#include "archive_private.h"
#include "archive_read_private.h"
#include "archive_write_disk_private.h"
struct extract {
struct archive *ad; /* archive_write_disk object */
/* Progress function invoked during extract. */
void (*extract_progress)(void *);
void *extract_progress_user_data;
};
static int archive_read_extract_cleanup(struct archive_read *);
static int copy_data(struct archive *ar, struct archive *aw);
static struct extract *get_extract(struct archive_read *);
static struct extract *
get_extract(struct archive_read *a)
{
/* If we haven't initialized, do it now. */
/* This also sets up a lot of global state. */
if (a->extract == NULL) {
a->extract = (struct extract *)malloc(sizeof(*a->extract));
if (a->extract == NULL) {
archive_set_error(&a->archive, ENOMEM, "Can't extract");
return (NULL);
}
memset(a->extract, 0, sizeof(*a->extract));
a->extract->ad = archive_write_disk_new();
if (a->extract->ad == NULL) {
archive_set_error(&a->archive, ENOMEM, "Can't extract");
return (NULL);
}
archive_write_disk_set_standard_lookup(a->extract->ad);
a->cleanup_archive_extract = archive_read_extract_cleanup;
}
return (a->extract);
}
int
archive_read_extract(struct archive *_a, struct archive_entry *entry, int flags)
{
struct extract *extract;
extract = get_extract((struct archive_read *)_a);
if (extract == NULL)
return (ARCHIVE_FATAL);
archive_write_disk_set_options(extract->ad, flags);
return (archive_read_extract2(_a, entry, extract->ad));
}
int
archive_read_extract2(struct archive *_a, struct archive_entry *entry,
struct archive *ad)
{
struct archive_read *a = (struct archive_read *)_a;
int r, r2;
/* Set up for this particular entry. */
if (a->skip_file_set)
archive_write_disk_set_skip_file(ad,
a->skip_file_dev, a->skip_file_ino);
r = archive_write_header(ad, entry);
if (r < ARCHIVE_WARN)
r = ARCHIVE_WARN;
if (r != ARCHIVE_OK)
/* If _write_header failed, copy the error. */
archive_copy_error(&a->archive, ad);
else if (!archive_entry_size_is_set(entry) || archive_entry_size(entry) > 0)
/* Otherwise, pour data into the entry. */
r = copy_data(_a, ad);
r2 = archive_write_finish_entry(ad);
if (r2 < ARCHIVE_WARN)
r2 = ARCHIVE_WARN;
/* Use the first message. */
if (r2 != ARCHIVE_OK && r == ARCHIVE_OK)
archive_copy_error(&a->archive, ad);
/* Use the worst error return. */
if (r2 < r)
r = r2;
return (r);
}
void
archive_read_extract_set_progress_callback(struct archive *_a,
void (*progress_func)(void *), void *user_data)
{
struct archive_read *a = (struct archive_read *)_a;
struct extract *extract = get_extract(a);
if (extract != NULL) {
extract->extract_progress = progress_func;
extract->extract_progress_user_data = user_data;
}
}
static int
copy_data(struct archive *ar, struct archive *aw)
{
int64_t offset;
const void *buff;
struct extract *extract;
size_t size;
int r;
extract = get_extract((struct archive_read *)ar);
if (extract == NULL)
return (ARCHIVE_FATAL);
for (;;) {
r = archive_read_data_block(ar, &buff, &size, &offset);
if (r == ARCHIVE_EOF)
return (ARCHIVE_OK);
if (r != ARCHIVE_OK)
return (r);
r = (int)archive_write_data_block(aw, buff, size, offset);
if (r < ARCHIVE_WARN)
r = ARCHIVE_WARN;
if (r != ARCHIVE_OK) {
archive_set_error(ar, archive_errno(aw),
"%s", archive_error_string(aw));
return (r);
}
if (extract->extract_progress)
(extract->extract_progress)
(extract->extract_progress_user_data);
}
}
/*
* Cleanup function for archive_extract.
*/
static int
archive_read_extract_cleanup(struct archive_read *a)
{
int ret = ARCHIVE_OK;
ret = archive_write_free(a->extract->ad);
free(a->extract);
a->extract = NULL;
return (ret);
}

View file

@ -0,0 +1,182 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_fd.c 201103 2009-12-28 03:13:49Z kientzle $");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_IO_H
#include <io.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "archive.h"
struct read_fd_data {
int fd;
size_t block_size;
char use_lseek;
void *buffer;
};
static int file_close(struct archive *, void *);
static ssize_t file_read(struct archive *, void *, const void **buff);
static int64_t file_skip(struct archive *, void *, int64_t request);
int
archive_read_open_fd(struct archive *a, int fd, size_t block_size)
{
struct stat st;
struct read_fd_data *mine;
void *b;
archive_clear_error(a);
if (fstat(fd, &st) != 0) {
archive_set_error(a, errno, "Can't stat fd %d", fd);
return (ARCHIVE_FATAL);
}
mine = (struct read_fd_data *)calloc(1, sizeof(*mine));
b = malloc(block_size);
if (mine == NULL || b == NULL) {
archive_set_error(a, ENOMEM, "No memory");
free(mine);
free(b);
return (ARCHIVE_FATAL);
}
mine->block_size = block_size;
mine->buffer = b;
mine->fd = fd;
/*
* Skip support is a performance optimization for anything
* that supports lseek(). On FreeBSD, only regular files and
* raw disk devices support lseek() and there's no portable
* way to determine if a device is a raw disk device, so we
* only enable this optimization for regular files.
*/
if (S_ISREG(st.st_mode)) {
archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
mine->use_lseek = 1;
}
#if defined(__CYGWIN__) || defined(_WIN32)
setmode(mine->fd, O_BINARY);
#endif
archive_read_set_read_callback(a, file_read);
archive_read_set_skip_callback(a, file_skip);
archive_read_set_close_callback(a, file_close);
archive_read_set_callback_data(a, mine);
return (archive_read_open1(a));
}
static ssize_t
file_read(struct archive *a, void *client_data, const void **buff)
{
struct read_fd_data *mine = (struct read_fd_data *)client_data;
ssize_t bytes_read;
*buff = mine->buffer;
for (;;) {
bytes_read = read(mine->fd, mine->buffer, mine->block_size);
if (bytes_read < 0) {
if (errno == EINTR)
continue;
archive_set_error(a, errno, "Error reading fd %d",
mine->fd);
}
return (bytes_read);
}
}
static int64_t
file_skip(struct archive *a, void *client_data, int64_t request)
{
struct read_fd_data *mine = (struct read_fd_data *)client_data;
int64_t skip = request;
int64_t old_offset, new_offset;
int skip_bits = sizeof(skip) * 8 - 1; /* off_t is a signed type. */
if (!mine->use_lseek)
return (0);
/* Reduce a request that would overflow the 'skip' variable. */
if (sizeof(request) > sizeof(skip)) {
int64_t max_skip =
(((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1;
if (request > max_skip)
skip = max_skip;
}
/* Reduce request to the next smallest multiple of block_size */
request = (request / mine->block_size) * mine->block_size;
if (request == 0)
return (0);
if (((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0) &&
((new_offset = lseek(mine->fd, skip, SEEK_CUR)) >= 0))
return (new_offset - old_offset);
/* If seek failed once, it will probably fail again. */
mine->use_lseek = 0;
/* Let libarchive recover with read+discard. */
if (errno == ESPIPE)
return (0);
/*
* There's been an error other than ESPIPE. This is most
* likely caused by a programmer error (too large request)
* or a corrupted archive file.
*/
archive_set_error(a, errno, "Error seeking");
return (-1);
}
static int
file_close(struct archive *a, void *client_data)
{
struct read_fd_data *mine = (struct read_fd_data *)client_data;
(void)a; /* UNUSED */
free(mine->buffer);
free(mine);
return (ARCHIVE_OK);
}

View file

@ -0,0 +1,177 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_file.c 201093 2009-12-28 02:28:44Z kientzle $");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_IO_H
#include <io.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "archive.h"
struct read_FILE_data {
FILE *f;
size_t block_size;
void *buffer;
char can_skip;
};
static int file_close(struct archive *, void *);
static ssize_t file_read(struct archive *, void *, const void **buff);
static int64_t file_skip(struct archive *, void *, int64_t request);
int
archive_read_open_FILE(struct archive *a, FILE *f)
{
struct stat st;
struct read_FILE_data *mine;
size_t block_size = 128 * 1024;
void *b;
archive_clear_error(a);
mine = (struct read_FILE_data *)malloc(sizeof(*mine));
b = malloc(block_size);
if (mine == NULL || b == NULL) {
archive_set_error(a, ENOMEM, "No memory");
free(mine);
free(b);
return (ARCHIVE_FATAL);
}
mine->block_size = block_size;
mine->buffer = b;
mine->f = f;
/*
* If we can't fstat() the file, it may just be that it's not
* a file. (FILE * objects can wrap many kinds of I/O
* streams, some of which don't support fileno()).)
*/
if (fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) {
archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
/* Enable the seek optimization only for regular files. */
mine->can_skip = 1;
} else
mine->can_skip = 0;
#if defined(__CYGWIN__) || defined(_WIN32)
setmode(fileno(mine->f), O_BINARY);
#endif
archive_read_set_read_callback(a, file_read);
archive_read_set_skip_callback(a, file_skip);
archive_read_set_close_callback(a, file_close);
archive_read_set_callback_data(a, mine);
return (archive_read_open1(a));
}
static ssize_t
file_read(struct archive *a, void *client_data, const void **buff)
{
struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
size_t bytes_read;
*buff = mine->buffer;
bytes_read = fread(mine->buffer, 1, mine->block_size, mine->f);
if (bytes_read < mine->block_size && ferror(mine->f)) {
archive_set_error(a, errno, "Error reading file");
}
return (bytes_read);
}
static int64_t
file_skip(struct archive *a, void *client_data, int64_t request)
{
struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
#if HAVE_FSEEKO
off_t skip = (off_t)request;
#elif HAVE__FSEEKI64
int64_t skip = request;
#else
long skip = (long)request;
#endif
int skip_bits = sizeof(skip) * 8 - 1;
(void)a; /* UNUSED */
/*
* If we can't skip, return 0 as the amount we did step and
* the caller will work around by reading and discarding.
*/
if (!mine->can_skip)
return (0);
if (request == 0)
return (0);
/* If request is too big for a long or an off_t, reduce it. */
if (sizeof(request) > sizeof(skip)) {
int64_t max_skip =
(((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1;
if (request > max_skip)
skip = max_skip;
}
#if HAVE_FSEEKO
if (fseeko(mine->f, skip, SEEK_CUR) != 0)
#elif HAVE__FSEEKI64
if (_fseeki64(mine->f, skip, SEEK_CUR) != 0)
#else
if (fseek(mine->f, skip, SEEK_CUR) != 0)
#endif
{
mine->can_skip = 0;
return (0);
}
return (request);
}
static int
file_close(struct archive *a, void *client_data)
{
struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
(void)a; /* UNUSED */
if (mine->buffer != NULL)
free(mine->buffer);
free(mine);
return (ARCHIVE_OK);
}

View file

@ -0,0 +1,574 @@
/*-
* Copyright (c) 2003-2010 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_filename.c 201093 2009-12-28 02:28:44Z kientzle $");
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_IO_H
#include <io.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <sys/disk.h>
#elif defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/disklabel.h>
#include <sys/dkio.h>
#elif defined(__DragonFly__)
#include <sys/diskslice.h>
#endif
#include "archive.h"
#include "archive_private.h"
#include "archive_string.h"
#ifndef O_BINARY
#define O_BINARY 0
#endif
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif
struct read_file_data {
int fd;
size_t block_size;
void *buffer;
mode_t st_mode; /* Mode bits for opened file. */
char use_lseek;
enum fnt_e { FNT_STDIN, FNT_MBS, FNT_WCS } filename_type;
union {
char m[1];/* MBS filename. */
wchar_t w[1];/* WCS filename. */
} filename; /* Must be last! */
};
static int file_open(struct archive *, void *);
static int file_close(struct archive *, void *);
static int file_close2(struct archive *, void *);
static int file_switch(struct archive *, void *, void *);
static ssize_t file_read(struct archive *, void *, const void **buff);
static int64_t file_seek(struct archive *, void *, int64_t request, int);
static int64_t file_skip(struct archive *, void *, int64_t request);
static int64_t file_skip_lseek(struct archive *, void *, int64_t request);
int
archive_read_open_file(struct archive *a, const char *filename,
size_t block_size)
{
return (archive_read_open_filename(a, filename, block_size));
}
int
archive_read_open_filename(struct archive *a, const char *filename,
size_t block_size)
{
const char *filenames[2] = { filename, NULL };
return archive_read_open_filenames(a, filenames, block_size);
}
int
archive_read_open_filenames(struct archive *a, const char **filenames,
size_t block_size)
{
struct read_file_data *mine;
const char *filename = NULL;
if (filenames)
filename = *(filenames++);
archive_clear_error(a);
do
{
if (filename == NULL)
filename = "";
mine = (struct read_file_data *)calloc(1,
sizeof(*mine) + strlen(filename));
if (mine == NULL)
goto no_memory;
strcpy(mine->filename.m, filename);
mine->block_size = block_size;
mine->fd = -1;
mine->buffer = NULL;
mine->st_mode = mine->use_lseek = 0;
if (filename == NULL || filename[0] == '\0') {
mine->filename_type = FNT_STDIN;
} else
mine->filename_type = FNT_MBS;
if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK))
return (ARCHIVE_FATAL);
if (filenames == NULL)
break;
filename = *(filenames++);
} while (filename != NULL && filename[0] != '\0');
archive_read_set_open_callback(a, file_open);
archive_read_set_read_callback(a, file_read);
archive_read_set_skip_callback(a, file_skip);
archive_read_set_close_callback(a, file_close);
archive_read_set_switch_callback(a, file_switch);
archive_read_set_seek_callback(a, file_seek);
return (archive_read_open1(a));
no_memory:
archive_set_error(a, ENOMEM, "No memory");
return (ARCHIVE_FATAL);
}
int
archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename,
size_t block_size)
{
struct read_file_data *mine = (struct read_file_data *)calloc(1,
sizeof(*mine) + wcslen(wfilename) * sizeof(wchar_t));
if (!mine)
{
archive_set_error(a, ENOMEM, "No memory");
return (ARCHIVE_FATAL);
}
mine->fd = -1;
mine->block_size = block_size;
if (wfilename == NULL || wfilename[0] == L'\0') {
mine->filename_type = FNT_STDIN;
} else {
#if defined(_WIN32) && !defined(__CYGWIN__)
mine->filename_type = FNT_WCS;
wcscpy(mine->filename.w, wfilename);
#else
/*
* POSIX system does not support a wchar_t interface for
* open() system call, so we have to translate a whcar_t
* filename to multi-byte one and use it.
*/
struct archive_string fn;
archive_string_init(&fn);
if (archive_string_append_from_wcs(&fn, wfilename,
wcslen(wfilename)) != 0) {
if (errno == ENOMEM)
archive_set_error(a, errno,
"Can't allocate memory");
else
archive_set_error(a, EINVAL,
"Failed to convert a wide-character"
" filename to a multi-byte filename");
archive_string_free(&fn);
free(mine);
return (ARCHIVE_FATAL);
}
mine->filename_type = FNT_MBS;
strcpy(mine->filename.m, fn.s);
archive_string_free(&fn);
#endif
}
if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK))
return (ARCHIVE_FATAL);
archive_read_set_open_callback(a, file_open);
archive_read_set_read_callback(a, file_read);
archive_read_set_skip_callback(a, file_skip);
archive_read_set_close_callback(a, file_close);
archive_read_set_switch_callback(a, file_switch);
archive_read_set_seek_callback(a, file_seek);
return (archive_read_open1(a));
}
static int
file_open(struct archive *a, void *client_data)
{
struct stat st;
struct read_file_data *mine = (struct read_file_data *)client_data;
void *buffer;
const char *filename = NULL;
const wchar_t *wfilename = NULL;
int fd;
int is_disk_like = 0;
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
off_t mediasize = 0; /* FreeBSD-specific, so off_t okay here. */
#elif defined(__NetBSD__) || defined(__OpenBSD__)
struct disklabel dl;
#elif defined(__DragonFly__)
struct partinfo pi;
#endif
archive_clear_error(a);
if (mine->filename_type == FNT_STDIN) {
/* We used to delegate stdin support by
* directly calling archive_read_open_fd(a,0,block_size)
* here, but that doesn't (and shouldn't) handle the
* end-of-file flush when reading stdout from a pipe.
* Basically, read_open_fd() is intended for folks who
* are willing to handle such details themselves. This
* API is intended to be a little smarter for folks who
* want easy handling of the common case.
*/
fd = 0;
#if defined(__CYGWIN__) || defined(_WIN32)
setmode(0, O_BINARY);
#endif
filename = "";
} else if (mine->filename_type == FNT_MBS) {
filename = mine->filename.m;
fd = open(filename, O_RDONLY | O_BINARY | O_CLOEXEC);
__archive_ensure_cloexec_flag(fd);
if (fd < 0) {
archive_set_error(a, errno,
"Failed to open '%s'", filename);
return (ARCHIVE_FATAL);
}
} else {
#if defined(_WIN32) && !defined(__CYGWIN__)
wfilename = mine->filename.w;
fd = _wopen(wfilename, O_RDONLY | O_BINARY);
if (fd < 0 && errno == ENOENT) {
wchar_t *fullpath;
fullpath = __la_win_permissive_name_w(wfilename);
if (fullpath != NULL) {
fd = _wopen(fullpath, O_RDONLY | O_BINARY);
free(fullpath);
}
}
if (fd < 0) {
archive_set_error(a, errno,
"Failed to open '%S'", wfilename);
return (ARCHIVE_FATAL);
}
#else
archive_set_error(a, ARCHIVE_ERRNO_MISC,
"Unexpedted operation in archive_read_open_filename");
return (ARCHIVE_FATAL);
#endif
}
if (fstat(fd, &st) != 0) {
if (mine->filename_type == FNT_WCS)
archive_set_error(a, errno, "Can't stat '%S'",
wfilename);
else
archive_set_error(a, errno, "Can't stat '%s'",
filename);
return (ARCHIVE_FATAL);
}
/*
* Determine whether the input looks like a disk device or a
* tape device. The results are used below to select an I/O
* strategy:
* = "disk-like" devices support arbitrary lseek() and will
* support I/O requests of any size. So we get easy skipping
* and can cheat on block sizes to get better performance.
* = "tape-like" devices require strict blocking and use
* specialized ioctls for seeking.
* = "socket-like" devices cannot seek at all but can improve
* performance by using nonblocking I/O to read "whatever is
* available right now".
*
* Right now, we only specially recognize disk-like devices,
* but it should be straightforward to add probes and strategy
* here for tape-like and socket-like devices.
*/
if (S_ISREG(st.st_mode)) {
/* Safety: Tell the extractor not to overwrite the input. */
archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
/* Regular files act like disks. */
is_disk_like = 1;
}
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
/* FreeBSD: if it supports DIOCGMEDIASIZE ioctl, it's disk-like. */
else if (S_ISCHR(st.st_mode) &&
ioctl(fd, DIOCGMEDIASIZE, &mediasize) == 0 &&
mediasize > 0) {
is_disk_like = 1;
}
#elif defined(__NetBSD__) || defined(__OpenBSD__)
/* Net/OpenBSD: if it supports DIOCGDINFO ioctl, it's disk-like. */
else if ((S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) &&
ioctl(fd, DIOCGDINFO, &dl) == 0 &&
dl.d_partitions[DISKPART(st.st_rdev)].p_size > 0) {
is_disk_like = 1;
}
#elif defined(__DragonFly__)
/* DragonFly BSD: if it supports DIOCGPART ioctl, it's disk-like. */
else if (S_ISCHR(st.st_mode) &&
ioctl(fd, DIOCGPART, &pi) == 0 &&
pi.media_size > 0) {
is_disk_like = 1;
}
#elif defined(__linux__)
/* Linux: All block devices are disk-like. */
else if (S_ISBLK(st.st_mode) &&
lseek(fd, 0, SEEK_CUR) == 0 &&
lseek(fd, 0, SEEK_SET) == 0 &&
lseek(fd, 0, SEEK_END) > 0 &&
lseek(fd, 0, SEEK_SET) == 0) {
is_disk_like = 1;
}
#endif
/* TODO: Add an "is_tape_like" variable and appropriate tests. */
/* Disk-like devices prefer power-of-two block sizes. */
/* Use provided block_size as a guide so users have some control. */
if (is_disk_like) {
size_t new_block_size = 64 * 1024;
while (new_block_size < mine->block_size
&& new_block_size < 64 * 1024 * 1024)
new_block_size *= 2;
mine->block_size = new_block_size;
}
buffer = malloc(mine->block_size);
if (mine == NULL || buffer == NULL) {
archive_set_error(a, ENOMEM, "No memory");
free(mine);
free(buffer);
return (ARCHIVE_FATAL);
}
mine->buffer = buffer;
mine->fd = fd;
/* Remember mode so close can decide whether to flush. */
mine->st_mode = st.st_mode;
/* Disk-like inputs can use lseek(). */
if (is_disk_like)
mine->use_lseek = 1;
return (ARCHIVE_OK);
}
static ssize_t
file_read(struct archive *a, void *client_data, const void **buff)
{
struct read_file_data *mine = (struct read_file_data *)client_data;
ssize_t bytes_read;
/* TODO: If a recent lseek() operation has left us
* mis-aligned, read and return a short block to try to get
* us back in alignment. */
/* TODO: Someday, try mmap() here; if that succeeds, give
* the entire file to libarchive as a single block. That
* could be a lot faster than block-by-block manual I/O. */
/* TODO: We might be able to improve performance on pipes and
* sockets by setting non-blocking I/O and just accepting
* whatever we get here instead of waiting for a full block
* worth of data. */
*buff = mine->buffer;
for (;;) {
bytes_read = read(mine->fd, mine->buffer, mine->block_size);
if (bytes_read < 0) {
if (errno == EINTR)
continue;
else if (mine->filename_type == FNT_STDIN)
archive_set_error(a, errno,
"Error reading stdin");
else if (mine->filename_type == FNT_MBS)
archive_set_error(a, errno,
"Error reading '%s'", mine->filename.m);
else
archive_set_error(a, errno,
"Error reading '%S'", mine->filename.w);
}
return (bytes_read);
}
}
/*
* Regular files and disk-like block devices can use simple lseek
* without needing to round the request to the block size.
*
* TODO: This can leave future reads mis-aligned. Since we know the
* offset here, we should store it and use it in file_read() above
* to determine whether we should perform a short read to get back
* into alignment. Long series of mis-aligned reads can negatively
* impact disk throughput. (Of course, the performance impact should
* be carefully tested; extra code complexity is only worthwhile if
* it does provide measurable improvement.)
*
* TODO: Be lazy about the actual seek. There are a few pathological
* cases where libarchive makes a bunch of seek requests in a row
* without any intervening reads. This isn't a huge performance
* problem, since the kernel handles seeks lazily already, but
* it would be very slightly faster if we simply remembered the
* seek request here and then actually performed the seek at the
* top of the read callback above.
*/
static int64_t
file_skip_lseek(struct archive *a, void *client_data, int64_t request)
{
struct read_file_data *mine = (struct read_file_data *)client_data;
#if defined(_WIN32) && !defined(__CYGWIN__)
/* We use _lseeki64() on Windows. */
int64_t old_offset, new_offset;
#else
off_t old_offset, new_offset;
#endif
/* We use off_t here because lseek() is declared that way. */
/* TODO: Deal with case where off_t isn't 64 bits.
* This shouldn't be a problem on Linux or other POSIX
* systems, since the configuration logic for libarchive
* tries to obtain a 64-bit off_t.
*/
if ((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0 &&
(new_offset = lseek(mine->fd, request, SEEK_CUR)) >= 0)
return (new_offset - old_offset);
/* If lseek() fails, don't bother trying again. */
mine->use_lseek = 0;
/* Let libarchive recover with read+discard */
if (errno == ESPIPE)
return (0);
/* If the input is corrupted or truncated, fail. */
if (mine->filename_type == FNT_STDIN)
archive_set_error(a, errno, "Error seeking in stdin");
else if (mine->filename_type == FNT_MBS)
archive_set_error(a, errno, "Error seeking in '%s'",
mine->filename.m);
else
archive_set_error(a, errno, "Error seeking in '%S'",
mine->filename.w);
return (-1);
}
/*
* TODO: Implement another file_skip_XXXX that uses MTIO ioctls to
* accelerate operation on tape drives.
*/
static int64_t
file_skip(struct archive *a, void *client_data, int64_t request)
{
struct read_file_data *mine = (struct read_file_data *)client_data;
/* Delegate skip requests. */
if (mine->use_lseek)
return (file_skip_lseek(a, client_data, request));
/* If we can't skip, return 0; libarchive will read+discard instead. */
return (0);
}
/*
* TODO: Store the offset and use it in the read callback.
*/
static int64_t
file_seek(struct archive *a, void *client_data, int64_t request, int whence)
{
struct read_file_data *mine = (struct read_file_data *)client_data;
int64_t r;
/* We use off_t here because lseek() is declared that way. */
/* See above for notes about when off_t is less than 64 bits. */
r = lseek(mine->fd, request, whence);
if (r >= 0)
return r;
/* If the input is corrupted or truncated, fail. */
if (mine->filename_type == FNT_STDIN)
archive_set_error(a, errno, "Error seeking in stdin");
else if (mine->filename_type == FNT_MBS)
archive_set_error(a, errno, "Error seeking in '%s'",
mine->filename.m);
else
archive_set_error(a, errno, "Error seeking in '%S'",
mine->filename.w);
return (ARCHIVE_FATAL);
}
static int
file_close2(struct archive *a, void *client_data)
{
struct read_file_data *mine = (struct read_file_data *)client_data;
(void)a; /* UNUSED */
/* Only flush and close if open succeeded. */
if (mine->fd >= 0) {
/*
* Sometimes, we should flush the input before closing.
* Regular files: faster to just close without flush.
* Disk-like devices: Ditto.
* Tapes: must not flush (user might need to
* read the "next" item on a non-rewind device).
* Pipes and sockets: must flush (otherwise, the
* program feeding the pipe or socket may complain).
* Here, I flush everything except for regular files and
* device nodes.
*/
if (!S_ISREG(mine->st_mode)
&& !S_ISCHR(mine->st_mode)
&& !S_ISBLK(mine->st_mode)) {
ssize_t bytesRead;
do {
bytesRead = read(mine->fd, mine->buffer,
mine->block_size);
} while (bytesRead > 0);
}
/* If a named file was opened, then it needs to be closed. */
if (mine->filename_type != FNT_STDIN)
close(mine->fd);
}
free(mine->buffer);
mine->buffer = NULL;
mine->fd = -1;
return (ARCHIVE_OK);
}
static int
file_close(struct archive *a, void *client_data)
{
struct read_file_data *mine = (struct read_file_data *)client_data;
file_close2(a, client_data);
free(mine);
return (ARCHIVE_OK);
}
static int
file_switch(struct archive *a, void *client_data1, void *client_data2)
{
file_close2(a, client_data1);
return file_open(a, client_data2);
}

View file

@ -0,0 +1,187 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_open_memory.c,v 1.6 2007/07/06 15:51:59 kientzle Exp $");
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "archive.h"
/*
* Glue to read an archive from a block of memory.
*
* This is mostly a huge help in building test harnesses;
* test programs can build archives in memory and read them
* back again without having to mess with files on disk.
*/
struct read_memory_data {
unsigned char *start;
unsigned char *p;
unsigned char *end;
ssize_t read_size;
};
static int memory_read_close(struct archive *, void *);
static int memory_read_open(struct archive *, void *);
static int64_t memory_read_seek(struct archive *, void *, int64_t offset, int whence);
static int64_t memory_read_skip(struct archive *, void *, int64_t request);
static ssize_t memory_read(struct archive *, void *, const void **buff);
int
archive_read_open_memory(struct archive *a, void *buff, size_t size)
{
return archive_read_open_memory2(a, buff, size, size);
}
/*
* Don't use _open_memory2() in production code; the archive_read_open_memory()
* version is the one you really want. This is just here so that
* test harnesses can exercise block operations inside the library.
*/
int
archive_read_open_memory2(struct archive *a, void *buff,
size_t size, size_t read_size)
{
struct read_memory_data *mine;
mine = (struct read_memory_data *)malloc(sizeof(*mine));
if (mine == NULL) {
archive_set_error(a, ENOMEM, "No memory");
return (ARCHIVE_FATAL);
}
memset(mine, 0, sizeof(*mine));
mine->start = mine->p = (unsigned char *)buff;
mine->end = mine->start + size;
mine->read_size = read_size;
archive_read_set_open_callback(a, memory_read_open);
archive_read_set_read_callback(a, memory_read);
archive_read_set_seek_callback(a, memory_read_seek);
archive_read_set_skip_callback(a, memory_read_skip);
archive_read_set_close_callback(a, memory_read_close);
archive_read_set_callback_data(a, mine);
return (archive_read_open1(a));
}
/*
* There's nothing to open.
*/
static int
memory_read_open(struct archive *a, void *client_data)
{
(void)a; /* UNUSED */
(void)client_data; /* UNUSED */
return (ARCHIVE_OK);
}
/*
* This is scary simple: Just advance a pointer. Limiting
* to read_size is not technically necessary, but it exercises
* more of the internal logic when used with a small block size
* in a test harness. Production use should not specify a block
* size; then this is much faster.
*/
static ssize_t
memory_read(struct archive *a, void *client_data, const void **buff)
{
struct read_memory_data *mine = (struct read_memory_data *)client_data;
ssize_t size;
(void)a; /* UNUSED */
*buff = mine->p;
size = mine->end - mine->p;
if (size > mine->read_size)
size = mine->read_size;
mine->p += size;
return (size);
}
/*
* Advancing is just as simple. Again, this is doing more than
* necessary in order to better exercise internal code when used
* as a test harness.
*/
static int64_t
memory_read_skip(struct archive *a, void *client_data, int64_t skip)
{
struct read_memory_data *mine = (struct read_memory_data *)client_data;
(void)a; /* UNUSED */
if ((int64_t)skip > (int64_t)(mine->end - mine->p))
skip = mine->end - mine->p;
/* Round down to block size. */
skip /= mine->read_size;
skip *= mine->read_size;
mine->p += skip;
return (skip);
}
/*
* Seeking.
*/
static int64_t
memory_read_seek(struct archive *a, void *client_data, int64_t offset, int whence)
{
struct read_memory_data *mine = (struct read_memory_data *)client_data;
(void)a; /* UNUSED */
switch (whence) {
case SEEK_SET:
mine->p = mine->start + offset;
break;
case SEEK_CUR:
mine->p += offset;
break;
case SEEK_END:
mine->p = mine->end + offset;
break;
default:
return ARCHIVE_FATAL;
}
if (mine->p < mine->start) {
mine->p = mine->start;
return ARCHIVE_FAILED;
}
if (mine->p > mine->end) {
mine->p = mine->end;
return ARCHIVE_FAILED;
}
return (mine->p - mine->start);
}
/*
* Close is just cleaning up our one small bit of data.
*/
static int
memory_read_close(struct archive *a, void *client_data)
{
struct read_memory_data *mine = (struct read_memory_data *)client_data;
(void)a; /* UNUSED */
free(mine);
return (ARCHIVE_OK);
}

View file

@ -0,0 +1,244 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: head/lib/libarchive/archive_read_private.h 201088 2009-12-28 02:18:55Z kientzle $
*/
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_READ_PRIVATE_H_INCLUDED
#define ARCHIVE_READ_PRIVATE_H_INCLUDED
#include "archive.h"
#include "archive_string.h"
#include "archive_private.h"
struct archive_read;
struct archive_read_filter_bidder;
struct archive_read_filter;
/*
* How bidding works for filters:
* * The bid manager initializes the client-provided reader as the
* first filter.
* * It invokes the bidder for each registered filter with the
* current head filter.
* * The bidders can use archive_read_filter_ahead() to peek ahead
* at the incoming data to compose their bids.
* * The bid manager creates a new filter structure for the winning
* bidder and gives the winning bidder a chance to initialize it.
* * The new filter becomes the new top filter and we repeat the
* process.
* This ends only when no bidder provides a non-zero bid. Then
* we perform a similar dance with the registered format handlers.
*/
struct archive_read_filter_bidder {
/* Configuration data for the bidder. */
void *data;
/* Name of the filter */
const char *name;
/* Taste the upstream filter to see if we handle this. */
int (*bid)(struct archive_read_filter_bidder *,
struct archive_read_filter *);
/* Initialize a newly-created filter. */
int (*init)(struct archive_read_filter *);
/* Set an option for the filter bidder. */
int (*options)(struct archive_read_filter_bidder *,
const char *key, const char *value);
/* Release the bidder's configuration data. */
int (*free)(struct archive_read_filter_bidder *);
};
/*
* This structure is allocated within the archive_read core
* and initialized by archive_read and the init() method of the
* corresponding bidder above.
*/
struct archive_read_filter {
int64_t position;
/* Essentially all filters will need these values, so
* just declare them here. */
struct archive_read_filter_bidder *bidder; /* My bidder. */
struct archive_read_filter *upstream; /* Who I read from. */
struct archive_read *archive; /* Associated archive. */
/* Open a block for reading */
int (*open)(struct archive_read_filter *self);
/* Return next block. */
ssize_t (*read)(struct archive_read_filter *, const void **);
/* Skip forward this many bytes. */
int64_t (*skip)(struct archive_read_filter *self, int64_t request);
/* Seek to an absolute location. */
int64_t (*seek)(struct archive_read_filter *self, int64_t offset, int whence);
/* Close (just this filter) and free(self). */
int (*close)(struct archive_read_filter *self);
/* Function that handles switching from reading one block to the next/prev */
int (*sswitch)(struct archive_read_filter *self, unsigned int iindex);
/* My private data. */
void *data;
const char *name;
int code;
/* Used by reblocking logic. */
char *buffer;
size_t buffer_size;
char *next; /* Current read location. */
size_t avail; /* Bytes in my buffer. */
const void *client_buff; /* Client buffer information. */
size_t client_total;
const char *client_next;
size_t client_avail;
char end_of_file;
char closed;
char fatal;
};
/*
* The client looks a lot like a filter, so we just wrap it here.
*
* TODO: Make archive_read_filter and archive_read_client identical so
* that users of the library can easily register their own
* transformation filters. This will probably break the API/ABI and
* so should be deferred at least until libarchive 3.0.
*/
struct archive_read_data_node {
int64_t begin_position;
int64_t total_size;
void *data;
};
struct archive_read_client {
archive_open_callback *opener;
archive_read_callback *reader;
archive_skip_callback *skipper;
archive_seek_callback *seeker;
archive_close_callback *closer;
archive_switch_callback *switcher;
unsigned int nodes;
unsigned int cursor;
int64_t position;
struct archive_read_data_node *dataset;
};
struct archive_read {
struct archive archive;
struct archive_entry *entry;
/* Dev/ino of the archive being read/written. */
int skip_file_set;
int64_t skip_file_dev;
int64_t skip_file_ino;
/*
* Used by archive_read_data() to track blocks and copy
* data to client buffers, filling gaps with zero bytes.
*/
const char *read_data_block;
int64_t read_data_offset;
int64_t read_data_output_offset;
size_t read_data_remaining;
/*
* Used by formats/filters to determine the amount of data
* requested from a call to archive_read_data(). This is only
* useful when the format/filter has seek support.
*/
char read_data_is_posix_read;
size_t read_data_requested;
/* Callbacks to open/read/write/close client archive streams. */
struct archive_read_client client;
/* Registered filter bidders. */
struct archive_read_filter_bidder bidders[14];
/* Last filter in chain */
struct archive_read_filter *filter;
/* Whether to bypass filter bidding process */
int bypass_filter_bidding;
/* File offset of beginning of most recently-read header. */
int64_t header_position;
/* Nodes and offsets of compressed data block */
unsigned int data_start_node;
unsigned int data_end_node;
/*
* Format detection is mostly the same as compression
* detection, with one significant difference: The bidders
* use the read_ahead calls above to examine the stream rather
* than having the supervisor hand them a block of data to
* examine.
*/
struct archive_format_descriptor {
void *data;
const char *name;
int (*bid)(struct archive_read *, int best_bid);
int (*options)(struct archive_read *, const char *key,
const char *value);
int (*read_header)(struct archive_read *, struct archive_entry *);
int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *);
int (*read_data_skip)(struct archive_read *);
int64_t (*seek_data)(struct archive_read *, int64_t, int);
int (*cleanup)(struct archive_read *);
} formats[16];
struct archive_format_descriptor *format; /* Active format. */
/*
* Various information needed by archive_extract.
*/
struct extract *extract;
int (*cleanup_archive_extract)(struct archive_read *);
};
int __archive_read_register_format(struct archive_read *a,
void *format_data,
const char *name,
int (*bid)(struct archive_read *, int),
int (*options)(struct archive_read *, const char *, const char *),
int (*read_header)(struct archive_read *, struct archive_entry *),
int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
int (*read_data_skip)(struct archive_read *),
int64_t (*seek_data)(struct archive_read *, int64_t, int),
int (*cleanup)(struct archive_read *));
int __archive_read_get_bidder(struct archive_read *a,
struct archive_read_filter_bidder **bidder);
const void *__archive_read_ahead(struct archive_read *, size_t, ssize_t *);
const void *__archive_read_filter_ahead(struct archive_read_filter *,
size_t, ssize_t *);
int64_t __archive_read_seek(struct archive_read*, int64_t, int);
int64_t __archive_read_filter_seek(struct archive_read_filter *, int64_t, int);
int64_t __archive_read_consume(struct archive_read *, int64_t);
int64_t __archive_read_filter_consume(struct archive_read_filter *, int64_t);
int __archive_read_program(struct archive_read_filter *, const char *);
void __archive_read_free_filters(struct archive_read *);
int __archive_read_close_filters(struct archive_read *);
#endif

View file

@ -0,0 +1,105 @@
/*-
* Copyright (c) 2003-2012 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include "archive.h"
#include "archive_private.h"
#include "archive_read_private.h"
int
archive_read_set_format(struct archive *_a, int code)
{
int r1, r2, slots, i;
char str[10];
struct archive_read *a = (struct archive_read *)_a;
if ((r1 = archive_read_support_format_by_code(_a, code)) < (ARCHIVE_OK))
return r1;
r1 = r2 = (ARCHIVE_OK);
if (a->format)
r2 = (ARCHIVE_WARN);
switch (code & ARCHIVE_FORMAT_BASE_MASK)
{
case ARCHIVE_FORMAT_7ZIP:
strcpy(str, "7zip");
break;
case ARCHIVE_FORMAT_AR:
strcpy(str, "ar");
break;
case ARCHIVE_FORMAT_CAB:
strcpy(str, "cab");
break;
case ARCHIVE_FORMAT_CPIO:
strcpy(str, "cpio");
break;
case ARCHIVE_FORMAT_ISO9660:
strcpy(str, "iso9660");
break;
case ARCHIVE_FORMAT_LHA:
strcpy(str, "lha");
break;
case ARCHIVE_FORMAT_MTREE:
strcpy(str, "mtree");
break;
case ARCHIVE_FORMAT_RAR:
strcpy(str, "rar");
break;
case ARCHIVE_FORMAT_TAR:
strcpy(str, "tar");
break;
case ARCHIVE_FORMAT_XAR:
strcpy(str, "xar");
break;
case ARCHIVE_FORMAT_ZIP:
strcpy(str, "zip");
break;
default:
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
"Invalid format code specified");
return (ARCHIVE_FATAL);
}
slots = sizeof(a->formats) / sizeof(a->formats[0]);
a->format = &(a->formats[0]);
for (i = 0; i < slots; i++, a->format++) {
if (!a->format->name || !strcmp(a->format->name, str))
break;
}
if (!a->format->name || strcmp(a->format->name, str))
{
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
"Internal error: Unable to set format");
r1 = (ARCHIVE_FATAL);
}
return (r1 < r2) ? r1 : r2;
}

View file

@ -0,0 +1,156 @@
/*-
* Copyright (c) 2011 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD$");
#include "archive_read_private.h"
#include "archive_options_private.h"
static int archive_set_format_option(struct archive *a,
const char *m, const char *o, const char *v);
static int archive_set_filter_option(struct archive *a,
const char *m, const char *o, const char *v);
static int archive_set_option(struct archive *a,
const char *m, const char *o, const char *v);
int
archive_read_set_format_option(struct archive *a, const char *m, const char *o,
const char *v)
{
return _archive_set_option(a, m, o, v,
ARCHIVE_READ_MAGIC, "archive_read_set_format_option",
archive_set_format_option);
}
int
archive_read_set_filter_option(struct archive *a, const char *m, const char *o,
const char *v)
{
return _archive_set_option(a, m, o, v,
ARCHIVE_READ_MAGIC, "archive_read_set_filter_option",
archive_set_filter_option);
}
int
archive_read_set_option(struct archive *a, const char *m, const char *o,
const char *v)
{
return _archive_set_option(a, m, o, v,
ARCHIVE_READ_MAGIC, "archive_read_set_option",
archive_set_option);
}
int
archive_read_set_options(struct archive *a, const char *options)
{
return _archive_set_options(a, options,
ARCHIVE_READ_MAGIC, "archive_read_set_options",
archive_set_option);
}
static int
archive_set_format_option(struct archive *_a, const char *m, const char *o,
const char *v)
{
struct archive_read *a = (struct archive_read *)_a;
struct archive_format_descriptor *format;
size_t i;
int r, rv = ARCHIVE_WARN;
for (i = 0; i < sizeof(a->formats)/sizeof(a->formats[0]); i++) {
format = &a->formats[i];
if (format == NULL || format->options == NULL ||
format->name == NULL)
/* This format does not support option. */
continue;
if (m != NULL && strcmp(format->name, m) != 0)
continue;
a->format = format;
r = format->options(a, o, v);
a->format = NULL;
if (r == ARCHIVE_FATAL)
return (ARCHIVE_FATAL);
if (m != NULL)
return (r);
if (r == ARCHIVE_OK)
rv = ARCHIVE_OK;
}
/* If the format name didn't match, return a special code for
* _archive_set_option[s]. */
if (rv == ARCHIVE_WARN && m != NULL)
rv = ARCHIVE_WARN - 1;
return (rv);
}
static int
archive_set_filter_option(struct archive *_a, const char *m, const char *o,
const char *v)
{
struct archive_read *a = (struct archive_read *)_a;
struct archive_read_filter *filter;
struct archive_read_filter_bidder *bidder;
int r, rv = ARCHIVE_WARN;
for (filter = a->filter; filter != NULL; filter = filter->upstream) {
bidder = filter->bidder;
if (bidder == NULL)
continue;
if (bidder->options == NULL)
/* This bidder does not support option */
continue;
if (m != NULL && strcmp(filter->name, m) != 0)
continue;
r = bidder->options(bidder, o, v);
if (r == ARCHIVE_FATAL)
return (ARCHIVE_FATAL);
if (m != NULL)
return (r);
if (r == ARCHIVE_OK)
rv = ARCHIVE_OK;
}
/* If the filter name didn't match, return a special code for
* _archive_set_option[s]. */
if (rv == ARCHIVE_WARN && m != NULL)
rv = ARCHIVE_WARN - 1;
return (rv);
}
static int
archive_set_option(struct archive *a, const char *m, const char *o,
const char *v)
{
return _archive_set_either_option(a, m, o, v,
archive_set_format_option,
archive_set_filter_option);
}

View file

@ -0,0 +1,81 @@
/*-
* Copyright (c) 2003-2011 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD$");
#include "archive.h"
#include "archive_private.h"
#if ARCHIVE_VERSION_NUMBER < 4000000
/* Deprecated; remove in libarchive 4.0 */
int
archive_read_support_compression_all(struct archive *a)
{
return archive_read_support_filter_all(a);
}
#endif
int
archive_read_support_filter_all(struct archive *a)
{
archive_check_magic(a, ARCHIVE_READ_MAGIC,
ARCHIVE_STATE_NEW, "archive_read_support_filter_all");
/* Bzip falls back to "bunzip2" command-line */
archive_read_support_filter_bzip2(a);
/* The decompress code doesn't use an outside library. */
archive_read_support_filter_compress(a);
/* Gzip decompress falls back to "gzip -d" command-line. */
archive_read_support_filter_gzip(a);
/* Lzip falls back to "unlzip" command-line program. */
archive_read_support_filter_lzip(a);
/* The LZMA file format has a very weak signature, so it
* may not be feasible to keep this here, but we'll try.
* This will come back out if there are problems. */
/* Lzma falls back to "unlzma" command-line program. */
archive_read_support_filter_lzma(a);
/* Xz falls back to "unxz" command-line program. */
archive_read_support_filter_xz(a);
/* The decode code doesn't use an outside library. */
archive_read_support_filter_uu(a);
/* The decode code doesn't use an outside library. */
archive_read_support_filter_rpm(a);
/* The decode code always uses "lrzip -q -d" command-line. */
archive_read_support_filter_lrzip(a);
/* Lzop decompress falls back to "lzop -d" command-line. */
archive_read_support_filter_lzop(a);
/* The decode code always uses "grzip -d" command-line. */
archive_read_support_filter_grzip(a);
/* Note: We always return ARCHIVE_OK here, even if some of the
* above return ARCHIVE_WARN. The intent here is to enable
* "as much as possible." Clients who need specific
* compression should enable those individually so they can
* verify the level of support. */
/* Clear any warning messages set by the above functions. */
archive_clear_error(a);
return (ARCHIVE_OK);
}

View file

@ -0,0 +1,371 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_BZLIB_H
#include <bzlib.h>
#endif
#include "archive.h"
#include "archive_private.h"
#include "archive_read_private.h"
#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
struct private_data {
bz_stream stream;
char *out_block;
size_t out_block_size;
char valid; /* True = decompressor is initialized */
char eof; /* True = found end of compressed data. */
};
/* Bzip2 filter */
static ssize_t bzip2_filter_read(struct archive_read_filter *, const void **);
static int bzip2_filter_close(struct archive_read_filter *);
#endif
/*
* Note that we can detect bzip2 archives even if we can't decompress
* them. (In fact, we like detecting them because we can give better
* error messages.) So the bid framework here gets compiled even
* if bzlib is unavailable.
*/
static int bzip2_reader_bid(struct archive_read_filter_bidder *, struct archive_read_filter *);
static int bzip2_reader_init(struct archive_read_filter *);
static int bzip2_reader_free(struct archive_read_filter_bidder *);
#if ARCHIVE_VERSION_NUMBER < 4000000
/* Deprecated; remove in libarchive 4.0 */
int
archive_read_support_compression_bzip2(struct archive *a)
{
return archive_read_support_filter_bzip2(a);
}
#endif
int
archive_read_support_filter_bzip2(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
struct archive_read_filter_bidder *reader;
archive_check_magic(_a, ARCHIVE_READ_MAGIC,
ARCHIVE_STATE_NEW, "archive_read_support_filter_bzip2");
if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
reader->data = NULL;
reader->name = "bzip2";
reader->bid = bzip2_reader_bid;
reader->init = bzip2_reader_init;
reader->options = NULL;
reader->free = bzip2_reader_free;
#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
return (ARCHIVE_OK);
#else
archive_set_error(_a, ARCHIVE_ERRNO_MISC,
"Using external bzip2 program");
return (ARCHIVE_WARN);
#endif
}
static int
bzip2_reader_free(struct archive_read_filter_bidder *self){
(void)self; /* UNUSED */
return (ARCHIVE_OK);
}
/*
* Test whether we can handle this data.
*
* This logic returns zero if any part of the signature fails. It
* also tries to Do The Right Thing if a very short buffer prevents us
* from verifying as much as we would like.
*/
static int
bzip2_reader_bid(struct archive_read_filter_bidder *self, struct archive_read_filter *filter)
{
const unsigned char *buffer;
ssize_t avail;
int bits_checked;
(void)self; /* UNUSED */
/* Minimal bzip2 archive is 14 bytes. */
buffer = __archive_read_filter_ahead(filter, 14, &avail);
if (buffer == NULL)
return (0);
/* First three bytes must be "BZh" */
bits_checked = 0;
if (memcmp(buffer, "BZh", 3) != 0)
return (0);
bits_checked += 24;
/* Next follows a compression flag which must be an ASCII digit. */
if (buffer[3] < '1' || buffer[3] > '9')
return (0);
bits_checked += 5;
/* After BZh[1-9], there must be either a data block
* which begins with 0x314159265359 or an end-of-data
* marker of 0x177245385090. */
if (memcmp(buffer + 4, "\x31\x41\x59\x26\x53\x59", 6) == 0)
bits_checked += 48;
else if (memcmp(buffer + 4, "\x17\x72\x45\x38\x50\x90", 6) == 0)
bits_checked += 48;
else
return (0);
return (bits_checked);
}
#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR)
/*
* If we don't have the library on this system, we can't actually do the
* decompression. We can, however, still detect compressed archives
* and emit a useful message.
*/
static int
bzip2_reader_init(struct archive_read_filter *self)
{
int r;
r = __archive_read_program(self, "bzip2 -d");
/* Note: We set the format here even if __archive_read_program()
* above fails. We do, after all, know what the format is
* even if we weren't able to read it. */
self->code = ARCHIVE_FILTER_BZIP2;
self->name = "bzip2";
return (r);
}
#else
/*
* Setup the callbacks.
*/
static int
bzip2_reader_init(struct archive_read_filter *self)
{
static const size_t out_block_size = 64 * 1024;
void *out_block;
struct private_data *state;
self->code = ARCHIVE_FILTER_BZIP2;
self->name = "bzip2";
state = (struct private_data *)calloc(sizeof(*state), 1);
out_block = (unsigned char *)malloc(out_block_size);
if (state == NULL || out_block == NULL) {
archive_set_error(&self->archive->archive, ENOMEM,
"Can't allocate data for bzip2 decompression");
free(out_block);
free(state);
return (ARCHIVE_FATAL);
}
self->data = state;
state->out_block_size = out_block_size;
state->out_block = out_block;
self->read = bzip2_filter_read;
self->skip = NULL; /* not supported */
self->close = bzip2_filter_close;
return (ARCHIVE_OK);
}
/*
* Return the next block of decompressed data.
*/
static ssize_t
bzip2_filter_read(struct archive_read_filter *self, const void **p)
{
struct private_data *state;
size_t decompressed;
const char *read_buf;
ssize_t ret;
state = (struct private_data *)self->data;
if (state->eof) {
*p = NULL;
return (0);
}
/* Empty our output buffer. */
state->stream.next_out = state->out_block;
state->stream.avail_out = state->out_block_size;
/* Try to fill the output buffer. */
for (;;) {
if (!state->valid) {
if (bzip2_reader_bid(self->bidder, self->upstream) == 0) {
state->eof = 1;
*p = state->out_block;
decompressed = state->stream.next_out
- state->out_block;
return (decompressed);
}
/* Initialize compression library. */
ret = BZ2_bzDecompressInit(&(state->stream),
0 /* library verbosity */,
0 /* don't use low-mem algorithm */);
/* If init fails, try low-memory algorithm instead. */
if (ret == BZ_MEM_ERROR)
ret = BZ2_bzDecompressInit(&(state->stream),
0 /* library verbosity */,
1 /* do use low-mem algo */);
if (ret != BZ_OK) {
const char *detail = NULL;
int err = ARCHIVE_ERRNO_MISC;
switch (ret) {
case BZ_PARAM_ERROR:
detail = "invalid setup parameter";
break;
case BZ_MEM_ERROR:
err = ENOMEM;
detail = "out of memory";
break;
case BZ_CONFIG_ERROR:
detail = "mis-compiled library";
break;
}
archive_set_error(&self->archive->archive, err,
"Internal error initializing decompressor%s%s",
detail == NULL ? "" : ": ",
detail);
return (ARCHIVE_FATAL);
}
state->valid = 1;
}
/* stream.next_in is really const, but bzlib
* doesn't declare it so. <sigh> */
read_buf =
__archive_read_filter_ahead(self->upstream, 1, &ret);
if (read_buf == NULL) {
archive_set_error(&self->archive->archive,
ARCHIVE_ERRNO_MISC,
"truncated bzip2 input");
return (ARCHIVE_FATAL);
}
state->stream.next_in = (char *)(uintptr_t)read_buf;
state->stream.avail_in = ret;
/* There is no more data, return whatever we have. */
if (ret == 0) {
state->eof = 1;
*p = state->out_block;
decompressed = state->stream.next_out
- state->out_block;
return (decompressed);
}
/* Decompress as much as we can in one pass. */
ret = BZ2_bzDecompress(&(state->stream));
__archive_read_filter_consume(self->upstream,
state->stream.next_in - read_buf);
switch (ret) {
case BZ_STREAM_END: /* Found end of stream. */
switch (BZ2_bzDecompressEnd(&(state->stream))) {
case BZ_OK:
break;
default:
archive_set_error(&(self->archive->archive),
ARCHIVE_ERRNO_MISC,
"Failed to clean up decompressor");
return (ARCHIVE_FATAL);
}
state->valid = 0;
/* FALLTHROUGH */
case BZ_OK: /* Decompressor made some progress. */
/* If we filled our buffer, update stats and return. */
if (state->stream.avail_out == 0) {
*p = state->out_block;
decompressed = state->stream.next_out
- state->out_block;
return (decompressed);
}
break;
default: /* Return an error. */
archive_set_error(&self->archive->archive,
ARCHIVE_ERRNO_MISC, "bzip decompression failed");
return (ARCHIVE_FATAL);
}
}
}
/*
* Clean up the decompressor.
*/
static int
bzip2_filter_close(struct archive_read_filter *self)
{
struct private_data *state;
int ret = ARCHIVE_OK;
state = (struct private_data *)self->data;
if (state->valid) {
switch (BZ2_bzDecompressEnd(&state->stream)) {
case BZ_OK:
break;
default:
archive_set_error(&self->archive->archive,
ARCHIVE_ERRNO_MISC,
"Failed to clean up decompressor");
ret = ARCHIVE_FATAL;
}
state->valid = 0;
}
free(state->out_block);
free(state);
return (ret);
}
#endif /* HAVE_BZLIB_H && BZ_CONFIG_ERROR */

View file

@ -0,0 +1,455 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This code borrows heavily from "compress" source code, which is
* protected by the following copyright. (Clause 3 dropped by request
* of the Regents.)
*/
/*-
* Copyright (c) 1985, 1986, 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Diomidis Spinellis and James A. Woods, derived from original
* work by Spencer Thomas and Joseph Orost.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "archive.h"
#include "archive_private.h"
#include "archive_read_private.h"
/*
* Because LZW decompression is pretty simple, I've just implemented
* the whole decompressor here (cribbing from "compress" source code,
* of course), rather than relying on an external library. I have
* made an effort to clarify and simplify the algorithm, so the
* names and structure here don't exactly match those used by compress.
*/
struct private_data {
/* Input variables. */
const unsigned char *next_in;
size_t avail_in;
size_t consume_unnotified;
int bit_buffer;
int bits_avail;
size_t bytes_in_section;
/* Output variables. */
size_t out_block_size;
void *out_block;
/* Decompression status variables. */
int use_reset_code;
int end_of_stream; /* EOF status. */
int maxcode; /* Largest code. */
int maxcode_bits; /* Length of largest code. */
int section_end_code; /* When to increase bits. */
int bits; /* Current code length. */
int oldcode; /* Previous code. */
int finbyte; /* Last byte of prev code. */
/* Dictionary. */
int free_ent; /* Next dictionary entry. */
unsigned char suffix[65536];
uint16_t prefix[65536];
/*
* Scratch area for expanding dictionary entries. Note:
* "worst" case here comes from compressing /dev/zero: the
* last code in the dictionary will code a sequence of
* 65536-256 zero bytes. Thus, we need stack space to expand
* a 65280-byte dictionary entry. (Of course, 32640:1
* compression could also be considered the "best" case. ;-)
*/
unsigned char *stackp;
unsigned char stack[65300];
};
static int compress_bidder_bid(struct archive_read_filter_bidder *, struct archive_read_filter *);
static int compress_bidder_init(struct archive_read_filter *);
static int compress_bidder_free(struct archive_read_filter_bidder *);
static ssize_t compress_filter_read(struct archive_read_filter *, const void **);
static int compress_filter_close(struct archive_read_filter *);
static int getbits(struct archive_read_filter *, int n);
static int next_code(struct archive_read_filter *);
#if ARCHIVE_VERSION_NUMBER < 4000000
/* Deprecated; remove in libarchive 4.0 */
int
archive_read_support_compression_compress(struct archive *a)
{
return archive_read_support_filter_compress(a);
}
#endif
int
archive_read_support_filter_compress(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
struct archive_read_filter_bidder *bidder;
archive_check_magic(_a, ARCHIVE_READ_MAGIC,
ARCHIVE_STATE_NEW, "archive_read_support_filter_compress");
if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
bidder->data = NULL;
bidder->name = "compress (.Z)";
bidder->bid = compress_bidder_bid;
bidder->init = compress_bidder_init;
bidder->options = NULL;
bidder->free = compress_bidder_free;
return (ARCHIVE_OK);
}
/*
* Test whether we can handle this data.
* This logic returns zero if any part of the signature fails.
*/
static int
compress_bidder_bid(struct archive_read_filter_bidder *self,
struct archive_read_filter *filter)
{
const unsigned char *buffer;
ssize_t avail;
int bits_checked;
(void)self; /* UNUSED */
buffer = __archive_read_filter_ahead(filter, 2, &avail);
if (buffer == NULL)
return (0);
bits_checked = 0;
if (buffer[0] != 0x1F || buffer[1] != 0x9D)
return (0);
bits_checked += 16;
/*
* TODO: Verify more.
*/
return (bits_checked);
}
/*
* Setup the callbacks.
*/
static int
compress_bidder_init(struct archive_read_filter *self)
{
struct private_data *state;
static const size_t out_block_size = 64 * 1024;
void *out_block;
int code;
self->code = ARCHIVE_FILTER_COMPRESS;
self->name = "compress (.Z)";
state = (struct private_data *)calloc(sizeof(*state), 1);
out_block = malloc(out_block_size);
if (state == NULL || out_block == NULL) {
free(out_block);
free(state);
archive_set_error(&self->archive->archive, ENOMEM,
"Can't allocate data for %s decompression",
self->name);
return (ARCHIVE_FATAL);
}
self->data = state;
state->out_block_size = out_block_size;
state->out_block = out_block;
self->read = compress_filter_read;
self->skip = NULL; /* not supported */
self->close = compress_filter_close;
/* XXX MOVE THE FOLLOWING OUT OF INIT() XXX */
(void)getbits(self, 8); /* Skip first signature byte. */
(void)getbits(self, 8); /* Skip second signature byte. */
code = getbits(self, 8);
state->maxcode_bits = code & 0x1f;
state->maxcode = (1 << state->maxcode_bits);
state->use_reset_code = code & 0x80;
/* Initialize decompressor. */
state->free_ent = 256;
state->stackp = state->stack;
if (state->use_reset_code)
state->free_ent++;
state->bits = 9;
state->section_end_code = (1<<state->bits) - 1;
state->oldcode = -1;
for (code = 255; code >= 0; code--) {
state->prefix[code] = 0;
state->suffix[code] = code;
}
next_code(self);
return (ARCHIVE_OK);
}
/*
* Return a block of data from the decompression buffer. Decompress more
* as necessary.
*/
static ssize_t
compress_filter_read(struct archive_read_filter *self, const void **pblock)
{
struct private_data *state;
unsigned char *p, *start, *end;
int ret;
state = (struct private_data *)self->data;
if (state->end_of_stream) {
*pblock = NULL;
return (0);
}
p = start = (unsigned char *)state->out_block;
end = start + state->out_block_size;
while (p < end && !state->end_of_stream) {
if (state->stackp > state->stack) {
*p++ = *--state->stackp;
} else {
ret = next_code(self);
if (ret == -1)
state->end_of_stream = ret;
else if (ret != ARCHIVE_OK)
return (ret);
}
}
*pblock = start;
return (p - start);
}
/*
* Clean up the reader.
*/
static int
compress_bidder_free(struct archive_read_filter_bidder *self)
{
self->data = NULL;
return (ARCHIVE_OK);
}
/*
* Close and release the filter.
*/
static int
compress_filter_close(struct archive_read_filter *self)
{
struct private_data *state = (struct private_data *)self->data;
free(state->out_block);
free(state);
return (ARCHIVE_OK);
}
/*
* Process the next code and fill the stack with the expansion
* of the code. Returns ARCHIVE_FATAL if there is a fatal I/O or
* format error, ARCHIVE_EOF if we hit end of data, ARCHIVE_OK otherwise.
*/
static int
next_code(struct archive_read_filter *self)
{
struct private_data *state = (struct private_data *)self->data;
int code, newcode;
static int debug_buff[1024];
static unsigned debug_index;
code = newcode = getbits(self, state->bits);
if (code < 0)
return (code);
debug_buff[debug_index++] = code;
if (debug_index >= sizeof(debug_buff)/sizeof(debug_buff[0]))
debug_index = 0;
/* If it's a reset code, reset the dictionary. */
if ((code == 256) && state->use_reset_code) {
/*
* The original 'compress' implementation blocked its
* I/O in a manner that resulted in junk bytes being
* inserted after every reset. The next section skips
* this junk. (Yes, the number of *bytes* to skip is
* a function of the current *bit* length.)
*/
int skip_bytes = state->bits -
(state->bytes_in_section % state->bits);
skip_bytes %= state->bits;
state->bits_avail = 0; /* Discard rest of this byte. */
while (skip_bytes-- > 0) {
code = getbits(self, 8);
if (code < 0)
return (code);
}
/* Now, actually do the reset. */
state->bytes_in_section = 0;
state->bits = 9;
state->section_end_code = (1 << state->bits) - 1;
state->free_ent = 257;
state->oldcode = -1;
return (next_code(self));
}
if (code > state->free_ent) {
/* An invalid code is a fatal error. */
archive_set_error(&(self->archive->archive), -1,
"Invalid compressed data");
return (ARCHIVE_FATAL);
}
/* Special case for KwKwK string. */
if (code >= state->free_ent) {
*state->stackp++ = state->finbyte;
code = state->oldcode;
}
/* Generate output characters in reverse order. */
while (code >= 256) {
*state->stackp++ = state->suffix[code];
code = state->prefix[code];
}
*state->stackp++ = state->finbyte = code;
/* Generate the new entry. */
code = state->free_ent;
if (code < state->maxcode && state->oldcode >= 0) {
state->prefix[code] = state->oldcode;
state->suffix[code] = state->finbyte;
++state->free_ent;
}
if (state->free_ent > state->section_end_code) {
state->bits++;
state->bytes_in_section = 0;
if (state->bits == state->maxcode_bits)
state->section_end_code = state->maxcode;
else
state->section_end_code = (1 << state->bits) - 1;
}
/* Remember previous code. */
state->oldcode = newcode;
return (ARCHIVE_OK);
}
/*
* Return next 'n' bits from stream.
*
* -1 indicates end of available data.
*/
static int
getbits(struct archive_read_filter *self, int n)
{
struct private_data *state = (struct private_data *)self->data;
int code;
ssize_t ret;
static const int mask[] = {
0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff,
0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff
};
while (state->bits_avail < n) {
if (state->avail_in <= 0) {
if (state->consume_unnotified) {
__archive_read_filter_consume(self->upstream,
state->consume_unnotified);
state->consume_unnotified = 0;
}
state->next_in
= __archive_read_filter_ahead(self->upstream,
1, &ret);
if (ret == 0)
return (-1);
if (ret < 0 || state->next_in == NULL)
return (ARCHIVE_FATAL);
state->consume_unnotified = state->avail_in = ret;
}
state->bit_buffer |= *state->next_in++ << state->bits_avail;
state->avail_in--;
state->bits_avail += 8;
state->bytes_in_section++;
}
code = state->bit_buffer;
state->bit_buffer >>= n;
state->bits_avail -= n;
return (code & mask[n]);
}

View file

@ -0,0 +1,121 @@
/*-
* Copyright (c) 2012 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "archive.h"
#include "archive_private.h"
#include "archive_read_private.h"
static const unsigned char grzip_magic[] = {
0x47, 0x52, 0x5a, 0x69, 0x70, 0x49, 0x49, 0x00,
0x02, 0x04, 0x3a, 0x29 };
static int grzip_bidder_bid(struct archive_read_filter_bidder *,
struct archive_read_filter *);
static int grzip_bidder_init(struct archive_read_filter *);
static int
grzip_reader_free(struct archive_read_filter_bidder *self)
{
(void)self; /* UNUSED */
return (ARCHIVE_OK);
}
int
archive_read_support_filter_grzip(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
struct archive_read_filter_bidder *reader;
archive_check_magic(_a, ARCHIVE_READ_MAGIC,
ARCHIVE_STATE_NEW, "archive_read_support_filter_grzip");
if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK)
return (ARCHIVE_FATAL);
reader->data = NULL;
reader->bid = grzip_bidder_bid;
reader->init = grzip_bidder_init;
reader->options = NULL;
reader->free = grzip_reader_free;
/* This filter always uses an external program. */
archive_set_error(_a, ARCHIVE_ERRNO_MISC,
"Using external grzip program for grzip decompression");
return (ARCHIVE_WARN);
}
/*
* Bidder just verifies the header and returns the number of verified bits.
*/
static int
grzip_bidder_bid(struct archive_read_filter_bidder *self,
struct archive_read_filter *filter)
{
const unsigned char *p;
ssize_t avail;
(void)self; /* UNUSED */
p = __archive_read_filter_ahead(filter, sizeof(grzip_magic), &avail);
if (p == NULL || avail == 0)
return (0);
if (memcmp(p, grzip_magic, sizeof(grzip_magic)))
return (0);
return (sizeof(grzip_magic) * 8);
}
static int
grzip_bidder_init(struct archive_read_filter *self)
{
int r;
r = __archive_read_program(self, "grzip -d");
/* Note: We set the format here even if __archive_read_program()
* above fails. We do, after all, know what the format is
* even if we weren't able to read it. */
self->code = ARCHIVE_FILTER_GRZIP;
self->name = "grzip";
return (r);
}

Some files were not shown because too many files have changed in this diff Show more