Keep full libarchive distribution in vendor branch (prep for 3.2.0 update)

This commit is contained in:
mm 2016-05-11 10:10:11 +00:00
parent 2a5a80bf0b
commit 597b1a1e1d
84 changed files with 20797 additions and 0 deletions

4
.gitattributes vendored Normal file
View File

@ -0,0 +1,4 @@
.git* export-ignore
*.sh crlf=input
config.rpath crlf=input

84
.gitignore vendored Normal file
View File

@ -0,0 +1,84 @@
*.o
*.exe
*.lo
*.cmake
.libs/
Makefile
Makefile.in
aclocal.m4
autom4te.cache/
bsdcpio
bsdcpio_test
bsdtar
bsdtar_test
build/autoconf/compile
build/autoconf/config.guess
build/autoconf/config.sub
build/autoconf/depcomp
build/autoconf/install-sh
build/autoconf/libtool.m4
build/autoconf/ltmain.sh
build/autoconf/ltoptions.m4
build/autoconf/ltsugar.m4
build/autoconf/ltversion.m4
build/autoconf/lt~obsolete.m4
build/autoconf/missing
build/pkgconfig/libarchive.pc
config.h
config.h.in
config.h.in~
config.log
config.status
configure
cpio/.deps/
cpio/.dirstamp
cpio/test/.deps/
cpio/test/.dirstamp
cpio/test/list.h
libarchive.la
libarchive/.deps/
libarchive/.dirstamp
libarchive/test/.deps/
libarchive/test/.dirstamp
libarchive/test/list.h
libarchive_fe.la
libarchive_fe/.deps/
libarchive_fe/.dirstamp
libarchive_test
libtool
stamp-h1
tar/.deps/
tar/.dirstamp
tar/test/.deps/
tar/test/.dirstamp
tar/test/list.h
CMakeCache.txt
CMakeFiles/
DartConfiguration.tcl
cmake.tmp/
cpio/CMakeFiles/
cpio/test/CMakeFiles/
libarchive/CMakeFiles/
libarchive/test/CMakeFiles/
tar/CMakeFiles/
tar/test/CMakeFiles/
test_utils/.deps/
test_utils/.dirstamp
doc/html/*.html
doc/man/*.1
doc/man/*.3
doc/man/*.5
doc/pdf/*.pdf
doc/text/*.txt
doc/wiki/*.wiki
libarchive-*.tar.gz
libarchive-*.zip
Testing/
libarchive/libarchive.a
libarchive/libarchive.so
libarchive/libarchive.so.*
.DS_Store

1525
CMakeLists.txt Normal file

File diff suppressed because it is too large Load Diff

11
CTestConfig.cmake Normal file
View File

@ -0,0 +1,11 @@
# TODO: This file should be moved into the build/cmake directory...
# The libarchive CDash page appears at
# http://my.cdash.org/index.php?project=libarchive
set(CTEST_PROJECT_NAME "libarchive")
set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
set(CTEST_DROP_METHOD "http")
set(CTEST_DROP_SITE "my.cdash.org")
set(CTEST_DROP_LOCATION "/submit.php?project=libarchive")
set(CTEST_DROP_SITE_CDASH TRUE)

35
INSTALL Normal file
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.

1012
Makefile.am Normal file

File diff suppressed because it is too large Load Diff

35
build/README.txt Normal file
View File

@ -0,0 +1,35 @@
Notes on making a new release of libarchive
===========================================
The following serves as a guide for libarchive developers on the general
process to be followed when making a new release of libarchive.
* Update build/version with the version number of the release to be made.
* If the library's ABI has changed, the library's soname major version *MUST*
be updated. Update configure.ac and CMakeLists.txt appropriately.
- For configure.ac, the variable ARCHIVE_INTERFACE needs to be updated.
- For CMakeLists.txt, the variable INTERFACE_VERSION needs to be updated.
* Update the entries in the NEWS file accordingly.
* Run `build/makerelease.sh` from the top source directory. Running this script
will do the following.
- Removes all Makefile.am development build specific CFLAGS from
Makefile.am.
- Update configure scripts and header files with the appropriate version
number from build/version.
- Rebuild the documentation directory.
- Runs a full cmake build and test.
- Runs a full autotools build and test.
- Builds the .tar.gz and .zip distribution files.
* Commit all changed files into git.
- This should be build/version, NEWS, and the files edited by running
build/makerelease.sh.
* Tag the release appropriately. The tag should also have an appropriate
message.
- The git command is as follows:
$ git tag -m "Libarchive <version>" v<version>
Replace <version> with the version to be released.
* Copy all the generated wiki files and commit them into the libarchive.wiki
repository. Overwrite any preexisting files with the same name (these files
are always autogenerated from the libarchive release after every release).
* Update the libarchive.org website accordingly.
* Make an announcement to the libarchive-announce mailing list.

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++)])

696
build/autoconf/config.rpath Executable file
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

268
build/autoconf/iconv.m4 Normal file
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,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])

109
build/autoconf/lib-ld.m4 Normal file
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
])

777
build/autoconf/lib-link.m4 Normal file
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"
])

67
build/autogen.sh Executable file
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

36
build/bump-version.sh Executable file
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

97
build/clean.sh Executable file
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()

1143
build/cmake/config.h.in Normal file

File diff suppressed because it is too large Load Diff

58
build/makerelease.sh Executable file
View File

@ -0,0 +1,58 @@
#!/bin/sh
#
# This script exists primarily to document some of the
# steps needed when building an "official libarchive distribution".
# Feel free to hack it up as necessary to adjust to the peculiarities
# of a particular build environment.
#
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
set -ex
#
# Scrub the local tree before running the build tests below.
#
/bin/sh build/clean.sh
#
# Verify the CMake-generated build
#
mkdir -p _cmtest
cd _cmtest
cmake ..
make
make test
cd ..
rm -rf _cmtest
# TODO: Build distribution using cmake
#
# Construct and verify the autoconf build system
#
export MAKE_LIBARCHIVE_RELEASE="1"
/bin/sh build/autogen.sh
# Get the newest config.guess/config.sub from savannah.gnu.org
curl 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD' > build/autoconf/config.guess
curl 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD' > build/autoconf/config.sub
./configure
make distcheck
make dist-zip

View File

@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libarchive
Description: library that can create and read several streaming archive formats
Version: @VERSION@
Cflags: -I${includedir}
Libs: -L${libdir} -larchive
Libs.private: @LIBS@

View File

@ -0,0 +1,455 @@
#!/bin/sh
#
# This needs http://unicode.org/Public/6.0.0/ucd/UnicodeData.txt
#
inputfile="$1" # Expect UnicodeData.txt
outfile=archive_string_composition.h
pickout=/tmp/mk_unicode_composition_tbl$$.awk
pickout2=/tmp/mk_unicode_composition_tbl2$$.awk
#nfdtmp=/tmp/mk_unicode_decomposition_tmp$$.txt
nfdtmp="nfdtmpx"
#################################################################################
#
# Append the file header of "archive_string_composition.h"
#
#################################################################################
append_copyright()
{
cat > ${outfile} <<CR_END
/*-
* Copyright (c) 2011-2012 libarchive Project
* 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\$
*
*/
/*
* ATTENTION!
* This file is generated by build/utils/gen_archive_string_composition_h.sh
* from http://unicode.org/Public/6.0.0/ucd/UnicodeData.txt
*
* See also http://unicode.org/report/tr15/
*/
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_STRING_COMPOSITION_H_INCLUDED
#define ARCHIVE_STRING_COMPOSITION_H_INCLUDED
struct unicode_composition_table {
uint32_t cp1;
uint32_t cp2;
uint32_t nfc;
};
CR_END
}
#################################################################################
#
# awk script
#
#################################################################################
cat > ${pickout} <<AWK_END
#
BEGIN {
FS = ";"
min = "";
max = "";
cmd="sort | awk -F ' ' '{printf \"\\\\t{ 0x%s , 0x%s , 0x%s },\\\\n\",\$1,\$2,\$3}'"
nfdtbl="${nfdtmp}"
print "static const struct unicode_composition_table u_composition_table[] = {"
}
END {
close(cmd)
print "};"
print ""
#
# Output Canonical Combining Class tables used for translating NFD to NFC.
#
printf "#define CANONICAL_CLASS_MIN\\t0x%s\\n", min
printf "#define CANONICAL_CLASS_MAX\\t0x%s\\n", max
print ""
printf "#define IS_DECOMPOSABLE_BLOCK(uc)\\t\\\\\n"
printf "\\t(((uc)>>8) <= 0x%X && u_decomposable_blocks[(uc)>>8])\\n", highnum
printf "static const char u_decomposable_blocks[0x%X+1] = {\\n\\t", highnum
#
# Output blockmap
for (i = 0; i <= highnum; i++) {
if (i != 0 && i % 32 == 0)
printf "\\n\\t"
# Additionally Hangul[11XX(17), AC00(172) - D7FF(215)] is decomposable.
if (blockmap[i] || i == 17 || (i >= 172 && i <= 215))
printf "1,"
else
printf "0,"
}
printf "\\n};\\n\\n"
#
# Output a macro to get a canonical combining class.
#
print "/* Get Canonical Combining Class(CCC). */"
printf "#define CCC(uc)\\t\\\\\n"
printf "\\t(((uc) > 0x%s)?0:\\\\\\n", max
printf "\\tccc_val[ccc_val_index[ccc_index[(uc)>>8]][((uc)>>4)&0x0F]][(uc)&0x0F])\\n"
print ""
#
# Output a canonical combining class value table.
#
midcnt = 0
printf "/* The table of the value of Canonical Cimbining Class */\\n"
print "static const unsigned char ccc_val[][16] = {"
print " /* idx=0: XXXX0 - XXXXF */"
print " { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },"
for (h = 0; h <= highnum; h++) {
if (!blockmap[h])
continue;
for (m = 0; m < 16; m++) {
if (!xx_blockmap[h, m])
continue;
midcnt++
printf " /* idx=%d: %03X%1X0 - %03X%1XF */\\n {", midcnt, h, m, h, m
for (l = 0; l < 15; l++) {
printf "%d, ", xxx_blockmap[h, m, l]
}
printf "%d },\n", xxx_blockmap[h, m, 15]
}
}
printf "};\n"
#
# Output the index table of the canonical combining class value table.
#
cnt = 0
midcnt = 0
printf "\\n/* The index table to ccc_val[*][16] */\\n"
print "static const unsigned char ccc_val_index[][16] = {"
print " /* idx=0: XXX00 - XXXFF */"
print " { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },"
for (h = 0; h <= highnum; h++) {
if (!blockmap[h])
continue;
cnt++
printf " /* idx=%d: %03X00 - %03XFF */\\n {", cnt, h, h
for (m = 0; m < 16; m++) {
if (m != 0)
printf ","
if (xx_blockmap[h, m]) {
midcnt++
printf "%2d", midcnt
} else
printf " 0"
}
printf " },\\n"
}
printf "};\\n"
#
# Output the index table to the index table of the canonical combining
# class value table.
#
printf "\\n/* The index table to ccc_val_index[*][16] */\\n"
printf "static const unsigned char ccc_index[] = {\\n ", h
cnt = 0
for (h = 0; h <= highnum; h++) {
if (h != 0 && h % 24 == 0)
printf "\\n "
if (blockmap[h]) {
cnt++;
printf "%2d,", cnt
} else
printf " 0,"
}
print "};"
print ""
}
#
#
function hextoi(hex)
{
dec = 0
for (i=0; i < length(hex); i++) {
x = substr(hex, i+1, 1)
if (x ~/[0-9]/)
dec = dec * 16 + x;
else if (x == "A")
dec = dec * 16 + 10;
else if (x == "B")
dec = dec * 16 + 11;
else if (x == "C")
dec = dec * 16 + 12;
else if (x == "D")
dec = dec * 16 + 13;
else if (x == "E")
dec = dec * 16 + 14;
else if (x == "F")
dec = dec * 16 + 15;
}
return dec
}
#
# Collect Canonical Combining Class values.
#
\$4 ~/^[0-9A-F]+$/ {
if (\$4 !~/^0$/) {
if (min == "") {
min = \$1
}
max = \$1
high = substr(\$1, 1, length(\$1) -2)
highnum = hextoi(high)
mid = substr(\$1, length(\$1) -1, 1)
midnum = hextoi(mid)
low = substr(\$1, length(\$1), 1)
lownum = hextoi(low)
blockmap[highnum] = 1
xx_blockmap[highnum, midnum] = 1
xxx_blockmap[highnum, midnum, lownum] = \$4
}
}
#
# Following code points are not decomposed in MAC OS.
# U+2000 - U+2FFF
# U+F900 - U+FAFF
# U+2F800 - U+2FAFF
#
#\$1 ~/^2[0-9A-F][0-9A-F][0-9A-F]\$/ {
# next
#}
#\$1 ~/^F[9A][0-9A-F][0-9A-F]\$/ {
# next
#}
#\$1 ~/^2F[89A][0-9A-F][0-9A-F]\$/ {
# next
#}
#
# Exclusion code points specified by
# http://unicode.org/Public/6.0.0/ucd/CompositionExclusions.txt
##
# 1. Script Specifices
##
\$1 ~/^095[89ABCDEF]\$/ {
next
}
\$1 ~/^09D[CDF]\$/ {
next
}
\$1 ~/^0A3[36]\$/ {
next
}
\$1 ~/^0A5[9ABE]\$/ {
next
}
\$1 ~/^0B5[CD]\$/ {
next
}
\$1 ~/^0F4[3D]\$/ {
next
}
\$1 ~/^0F5[27C]\$/ {
next
}
\$1 ~/^0F69\$/ {
next
}
\$1 ~/^0F7[68]\$/ {
next
}
\$1 ~/^0F9[3D]\$/ {
next
}
\$1 ~/^0FA[27C]\$/ {
next
}
\$1 ~/^0FB9\$/ {
next
}
\$1 ~/^FB1[DF]\$/ {
next
}
\$1 ~/^FB2[ABCDEF]\$/ {
next
}
\$1 ~/^FB3[012345689ABCE]\$/ {
next
}
\$1 ~/^FB4[01346789ABCDE]\$/ {
next
}
##
# 2. Post Composition Version precomposed characters
##
\$1 ~/^2ADC\$/ {
next
}
\$1 ~/^1D15[EF]\$/ {
next
}
\$1 ~/^1D16[01234]\$/ {
next
}
\$1 ~/^1D1B[BCDEF]\$/ {
next
}
\$1 ~/^1D1C0\$/ {
next
}
##
# 3. Singleton Decompositions
##
\$1 ~/^034[01]\$/ {
next
}
\$1 ~/^037[4E]\$/ {
next
}
\$1 ~/^0387\$/ {
next
}
\$1 ~/^1F7[13579BD]\$/ {
next
}
\$1 ~/^1FB[BE]\$/ {
next
}
\$1 ~/^1FC[9B]\$/ {
next
}
\$1 ~/^1FD[3B]\$/ {
next
}
\$1 ~/^1FE[3BEF]\$/ {
next
}
\$1 ~/^1FF[9BD]\$/ {
next
}
\$1 ~/^200[01]\$/ {
next
}
\$1 ~/^212[6AB]\$/ {
next
}
\$1 ~/^232[9A]\$/ {
next
}
\$1 ~/^F9[0-9A-F][0-9A-F]\$/ {
next
}
\$1 ~/^FA0[0-9A-D]\$/ {
next
}
\$1 ~/^FA1[025-9A-E]\$/ {
next
}
\$1 ~/^FA2[0256A-D]\$/ {
next
}
\$1 ~/^FA[3-5][0-9A-F]\$/ {
next
}
\$1 ~/^FA6[0-9A-D]\$/ {
next
}
\$1 ~/^FA[7-9A-C][0-9A-F]\$/ {
next
}
\$1 ~/^FAD[0-9]\$/ {
next
}
\$1 ~/^2F[89][0-9A-F][0-9A-F]\$/ {
next
}
\$1 ~/^2FA0[0-9A-F]\$/ {
next
}
\$1 ~/^2FA1[0-9A-D]\$/ {
next
}
##
# 4. Non-Starter Decompositions
##
\$1 ~/^0344\$/ {
next
}
\$1 ~/^0F7[35]\$/ {
next
}
\$1 ~/^0F81\$/ {
next
}
#
# Output combinations for NFD ==> NFC.
#
\$6 ~/^[0-9A-F]+ [0-9A-F]+\$/ {
split(\$6, cp, " ")
if (length(\$1) == 4)
print "0"cp[1], "0"cp[2], "0"\$1 | cmd
else
print cp[1], cp[2], \$1 | cmd
# NFC ==> NFD table.
if (length(\$1) == 4)
print "0"\$1, "0"cp[1], "0"cp[2] >>nfdtbl
else
print \$1, cp[1], cp[2] >>nfdtbl
}
AWK_END
#################################################################################
# awk script
#
#################################################################################
cat > ${pickout2} <<AWK_END
#
BEGIN {
FS = " "
print "struct unicode_decomposition_table {"
print "\tuint32_t nfc;"
print "\tuint32_t cp1;"
print "\tuint32_t cp2;"
print "};"
print ""
print "static const struct unicode_decomposition_table u_decomposition_table[] = {"
}
END {
print "};"
print ""
}
{
printf "\t{ 0x%s , 0x%s , 0x%s },\n", \$1, \$2, \$3;
}
AWK_END
#################################################################################
#
# Run awk a script.
#
#################################################################################
append_copyright
awk -f ${pickout} ${inputfile} >> ${outfile}
awk -f ${pickout2} ${nfdtmp} >> ${outfile}
echo "#endif /* ARCHIVE_STRING_COMPOSITION_H_INCLUDED */" >> ${outfile}
echo "" >> ${outfile}
#
# Remove awk the script.
rm ${pickout}
rm ${pickout2}
rm ${nfdtmp}

1
build/version Normal file
View File

@ -0,0 +1 @@
3001002

788
configure.ac Normal file
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

59
contrib/README Normal file
View File

@ -0,0 +1,59 @@
Many people have graciously sent me configuration
files, small programs that use libarchive, and other
useful and interesting tidbits.
I do not support or use any of these; but if you can use them, enjoy!
======================================================================
From: Andre Stechert <andre@splunk.com>
libarchive_autodetect-st_lib_archive.m4
M4 macros for use with autoconf to detect whether a suitable
version of libarchive is installed on this system.
======================================================================
libarchive.spec
An RPM ".spec" file for building libarchive on most systems.
This apparently was originally developed by a group at pld-linux.org.
Several people have sent me different versions of this file.
======================================================================
From: Robert Meier <rm1023@dcx.com>
libarchive.1aix53.spec
As above, for use on AIX5.3.
======================================================================
psota-benchmark
Some scripts used by Jan Psota in benchmarking
various tar implementations.
I've edited his results slightly to correctly reflect that
bsdtar does not support a "compare" operation.
======================================================================
shar
A simple shar program written on top of libarchive.
======================================================================
untar.c
A very simple and very portable standalone program that can
extract basic ustar archives.
This does not use libarchive and so can be used to extract
the libarchive distribution on any system that has a C compiler
but does not have a tar program.
======================================================================

View File

@ -0,0 +1,160 @@
# $LastChangedRevision$, $LastChangedDate$
Summary: Library to create and read several different archive formats
Summary(pl): Biblioteka do tworzenia i odczytu ró¿nych formatów archiwów
Name: libarchive
Version: 2.0a3
Release: 1aix53
License: BSD
Group: Libraries
Source0: http://people.freebsd.org/~kientzle/libarchive/src/%{name}-%{version}.tar.gz
Patch: %{name}-0123457890.patch
URL: http://people.freebsd.org/~kientzle/libarchive/
Requires: glibc
Requires: zlib
Requires: bzip2
BuildRequires: gcc
BuildRequires: gcc-c++
BuildRequires: gawk
BuildRequires: zlib-devel
BuildRequires: bzip2
BuildRoot: %{_tmppath}/%{name}-%{version}-build
%description
Libarchive is a programming library that can create and read several
different streaming archive formats, including most popular TAR
variants and several CPIO formats. It can also write SHAR archives.
%description -l pl
Libarchive jest bibliotek± s³u¿ac± to tworzenia i odczytu wielu
ró¿nych strumieniowych formatów archiwów, w³±czaj±c w to popularne
odmiany TAR oraz wiele formatów CPIO. Biblioteka ta potrafi tak¿e
zapisywaæ archiwa SHAR.
%package devel
Summary: Header files for libarchive library
Summary(pl): Pliki nag³ówkowe biblioteki libarchive
Group: Development/Libraries
Requires: %{name} = %{version}-%{release}
%description devel
Header files for libarchive library.
%description devel -l pl
Pliki nag³ówkowe biblioteki libarchive.
%package static
Summary: Static libarchive library
Summary(pl): Statyczna biblioteka libarchive
Group: Development/Libraries
Requires: %{name}-devel = %{version}-%{release}
%description static
Static libarchive library.
%description static -l pl
Statyczna biblioteka libarchive.
%package -n bsdtar
Summary: bsdtar - tar(1) implementation based on libarchive
Summary(pl): bsdtar - implementacja programu tar(1) oparta na libarchive
Group: Applications/Archiving
Requires: %{name} = %{version}-%{release}
%description -n bsdtar
bsdtar - tar(1) implementation based on libarchive.
%description -n bsdtar -l pl
bsdtar - implementacja programu tar(1), oparta na libarchive.
%prep
%setup -q
%patch0 -p1
%build
# Specify paths to avoid use of vacpp
# -maix64 - required to use large files with aix-5.3
# -static - required for interoperability without copying libraries
# -D_BSD - required to include definition of makedev
# -X64 - required to assemble 64-bit COFF files
mkdir -p %{buildroot}
PATH=/opt/freeware/libexec:/opt/freeware/bin:/usr/local/bin:/usr/bin:/etc:/usr/sbin:/usr/ucb:/usr/bin/X11:/sbin:. \
CPATH=/opt/freeware/include:/usr/local/include \
LIBPATH=/opt/freeware/lib:/usr/local/lib:/usr/share/lib \
LD_LIBRARY_PATH=/opt/freeware/lib:/usr/local/lib:/usr/share/lib \
CFLAGS="$RPM_OPT_FLAGS -maix64 -static -D_BSD" \
CXXFLAGS="$RPM_OPT_FLAGS -maix64 -static -D_BSD" \
AR="ar -X64" \
./configure \
--prefix=%{_prefix} \
--libexecdir=%{_libexecdir} \
--mandir=%{_mandir} \
--infodir=%{_infodir} \
--enable-shared=yes \
--enable-static=yes \
| tee %{buildroot}/config.log
make | tee %{buildroot}/make.log
%install
[ "%buildroot" != "/" ] && [ -d %buildroot ] && rm -rf %buildroot;
make DESTDIR=%buildroot install
# original install builds, but does install bsdtar
cp .libs/%{name}.a %{buildroot}%{_libdir}
cp bsdtar %{buildroot}%{_bindir}
cp tar/bsdtar.1 %{buildroot}%{_mandir}/man1
%clean
rm -fr %buildroot
%files
%defattr(644,root,root,755)
%{_libdir}/libarchive.a
%files devel
%defattr(644,root,root,755)
%{_libdir}/libarchive.la
%{_includedir}/*.h
%doc %{_mandir}/man3/*
%doc %{_mandir}/man5/*
%files -n bsdtar
%defattr(644,root,root,755)
%attr(755,root,root) %{_bindir}/bsdtar
%doc %{_mandir}/man1/bsdtar.1*
%define date %(echo `LC_ALL="C" date +"%a %b %d %Y"`)
%changelog
* %{date} PLD Team <feedback@pld-linux.org>
All persons listed below can be reached at <cvs_login>@pld-linux.org
$Log: libarchive.spec,v $
Release 1aix53 2006/12/12 rm1023@dcx.com
- tweak for aix-5.3
- added libarchive-0123457890.patch for "0123457890" error
- replaced libarchive-1.3.1.tar.gz with libarchive-2.0a3.tar.gz
- removed obsolete -CVE-2006-5680.patch and -man_progname.patch
Revision 1.6 2006/11/15 10:41:28 qboosh
- BR: acl-devel,attr-devel
- devel deps
Revision 1.5 2006/11/08 22:22:25 twittner
- up to 1.3.1
- added BR: e2fsprogs-devel
- added -CVE-2006-5680.patch against entering an infinite
loop in corrupt archives
- added bsdtar package (bsdtar is included now in libarchive
sources)
- rel. 0.1 for testing
Revision 1.4 2005/12/15 18:26:36 twittner
- up to 1.2.37
- removed -shared.patch (no longer needed)
Revision 1.3 2005/10/05 17:00:12 arekm
- up to 1.02.034
Revision 1.2 2005/07/27 20:17:21 qboosh
- typo
Revision 1.1 2005/07/27 08:36:03 adamg
- new

147
contrib/libarchive.spec Normal file
View File

@ -0,0 +1,147 @@
# $LastChangedRevision$, $LastChangedDate$
Summary: Library to create and read several different archive formats
Summary(pl): Biblioteka do tworzenia i odczytu ró¿nych formatów archiwów
Name: libarchive
Version: 2.0a3
Release: 1
License: BSD
Group: Libraries
Source0: http://people.freebsd.org/~kientzle/libarchive/src/%{name}-%{version}.tar.gz
Patch: %{name}-0123457890.patch
URL: http://people.freebsd.org/~kientzle/libarchive/
Requires: glibc
Requires: zlib
Requires: bzip2
BuildRequires: gcc
BuildRequires: gcc-c++
BuildRequires: gawk
BuildRequires: zlib-devel
BuildRequires: bzip2
BuildRoot: %{_tmppath}/%{name}-%{version}-build
%description
Libarchive is a programming library that can create and read several
different streaming archive formats, including most popular TAR
variants and several CPIO formats. It can also write SHAR archives.
%description -l pl
Libarchive jest bibliotek± s³u¿ac± to tworzenia i odczytu wielu
ró¿nych strumieniowych formatów archiwów, w³±czaj±c w to popularne
odmiany TAR oraz wiele formatów CPIO. Biblioteka ta potrafi tak¿e
zapisywaæ archiwa SHAR.
%package devel
Summary: Header files for libarchive library
Summary(pl): Pliki nag³ówkowe biblioteki libarchive
Group: Development/Libraries
Requires: %{name} = %{version}-%{release}
%description devel
Header files for libarchive library.
%description devel -l pl
Pliki nag³ówkowe biblioteki libarchive.
%package static
Summary: Static libarchive library
Summary(pl): Statyczna biblioteka libarchive
Group: Development/Libraries
Requires: %{name}-devel = %{version}-%{release}
%description static
Static libarchive library.
%description static -l pl
Statyczna biblioteka libarchive.
%package -n bsdtar
Summary: bsdtar - tar(1) implementation based on libarchive
Summary(pl): bsdtar - implementacja programu tar(1) oparta na libarchive
Group: Applications/Archiving
Requires: %{name} = %{version}-%{release}
%description -n bsdtar
bsdtar - tar(1) implementation based on libarchive.
%description -n bsdtar -l pl
bsdtar - implementacja programu tar(1), oparta na libarchive.
%prep
%setup -q
%patch0 -p1
%build
mkdir -p %{buildroot}
./configure \
--prefix=%{_prefix} \
--libexecdir=%{_libexecdir} \
--mandir=%{_mandir} \
--infodir=%{_infodir} \
--enable-shared=yes \
--enable-static=yes \
| tee %{buildroot}/config.log
make | tee %{buildroot}/make.log
%install
[ "%buildroot" != "/" ] && [ -d %buildroot ] && rm -rf %buildroot;
make DESTDIR=%buildroot install
# original install builds, but does install bsdtar
cp .libs/%{name}.a %{buildroot}%{_libdir}
cp bsdtar %{buildroot}%{_bindir}
cp tar/bsdtar.1 %{buildroot}%{_mandir}/man1
%clean
rm -fr %buildroot
%files
%defattr(644,root,root,755)
%{_libdir}/libarchive.a
%files devel
%defattr(644,root,root,755)
%{_libdir}/libarchive.la
%{_includedir}/*.h
%doc %{_mandir}/man3/*
%doc %{_mandir}/man5/*
%files -n bsdtar
%defattr(644,root,root,755)
%attr(755,root,root) %{_bindir}/bsdtar
%doc %{_mandir}/man1/bsdtar.1*
%define date %(echo `LC_ALL="C" date +"%a %b %d %Y"`)
%changelog
* %{date} PLD Team <feedback@pld-linux.org>
All persons listed below can be reached at <cvs_login>@pld-linux.org
$Log: libarchive.spec,v $
Release 1 2006/12/12 rm1023@dcx.com
- added libarchive-0123457890.patch for "0123457890" error
- replaced libarchive-1.3.1.tar.gz with libarchive-2.0a3.tar.gz
- removed obsolete -CVE-2006-5680.patch and -man_progname.patch
Revision 1.6 2006/11/15 10:41:28 qboosh
- BR: acl-devel,attr-devel
- devel deps
Revision 1.5 2006/11/08 22:22:25 twittner
- up to 1.3.1
- added BR: e2fsprogs-devel
- added -CVE-2006-5680.patch against entering an infinite
loop in corrupt archives
- added bsdtar package (bsdtar is included now in libarchive
sources)
- rel. 0.1 for testing
Revision 1.4 2005/12/15 18:26:36 twittner
- up to 1.2.37
- removed -shared.patch (no longer needed)
Revision 1.3 2005/10/05 17:00:12 arekm
- up to 1.02.034
Revision 1.2 2005/07/27 20:17:21 qboosh
- typo
Revision 1.1 2005/07/27 08:36:03 adamg
- new

View File

@ -0,0 +1,154 @@
dnl
dnl @synopsis ST_LIB_ARCHIVE([ENABLED-DEFAULT])
dnl
dnl This macro figures out what's necessary to link a program against an
dnl instance of the BSD libarchive package by Tim Kientzle.
dnl
dnl See http://people.freebsd.org/~kientzle/libarchive/ for more info.
dnl
dnl It exports and substitutes the variables LIBARCHIVE_LIBS, LIBARCHIVE_LDFLAGS,
dnl and LIBARCHIVE_CPPFLAGS to appropriate values for the identified instance of
dnl libarchive. The values are AC_SUBST'd, so a user could, for example, simply
dnl include @LIBARCHIVE_CPPFLAGS@ in the definition of AM_CPPFLAGS in a Makefile.am.
dnl
dnl ENABLED-DEFAULT is either "yes" or "no" and determines whether the default value
dnl is --with-libarchive or --without-libarchive. It is not possible to specify a
dnl default directory. More simply, any reasonable choice for a default should just
dnl go into the auto-detect list.
dnl
dnl The macro defines the symbol HAVE_LIBARCHIVE if the library is found. You
dnl should use autoheader to include a definition for this symbol in a config.h
dnl file. Sample usage in a C/C++ source is as follows:
dnl
dnl #ifdef HAVE_LIBARCHIVE
dnl #include <archive.h>
dnl #endif /* HAVE_LIBARCHIVE */
dnl
dnl @category InstalledPackages
dnl @author Andre Stechert <andre@splunk.com>
dnl @version 2006-04-20
dnl @license GPLWithACException
AC_DEFUN([ST_LIB_ARCHIVE],
[
#
# Handle input from the configurer and blend with the requirements from the maintainer.
# We go through the trouble of creating a second set of variables other than the with_foo
# variables in order to be sure that error/corner cases have been cleaned up.
#
# After this statement, three trusted variable are defined.
#
# st_lib_archive_ENABLED will be either "yes" or "no". its value determines whether
# or not we bother with the rest of the checks and whether or not we export a
# bunch of variables.
#
# st_lib_archive_LOCATION will be either "auto" or "defined". if it is "auto", then
# we try a bunch of standard locations. if it is "defined", then we just try the value
# provided in st_lib_archive_DIR.
#
# st_lib_archive_DIR will contain the string provided by the user, provided that it's
# actually a directory.
#
AC_MSG_CHECKING([if libarchive is wanted])
AC_ARG_WITH([libarchive],
AS_HELP_STRING([--with-libarchive=DIR], [libarchive installation directory]),
[if test "x$with_libarchive" = "xno" ; then
st_lib_archive_ENABLED=no
elif test "x$with_libarchive" = "xyes" ; then
st_lib_archive_ENABLED=yes
st_lib_archive_LOCATION=auto
else
st_lib_archive_ENABLED=yes
st_lib_archive_LOCATION=defined
if test -d "$with_libarchive" ; then
st_lib_archive_DIR="$with_libarchive"
else
AC_MSG_ERROR([$with_libarchive is not a directory])
fi
fi],
[if test "x$1" = "xno" ; then
st_lib_archive_ENABLED=no
elif test "x$1" = "xyes" ; then
st_lib_archive_ENABLED=yes
else
st_lib_archive_ENABLED=yes
fi])
if test "$st_lib_archive_ENABLED" = "yes" ; then
AC_MSG_RESULT([yes])
#
# After this statement, one trusted variable is defined.
#
# st_lib_archive_LIB will be either "lib" or "lib64", depending on whether the configurer
# specified 32, 64. The default is "lib".
#
AC_MSG_CHECKING([whether to use lib or lib64])
AC_ARG_WITH([libarchive-bits],
AS_HELP_STRING([--with-libarchive-bits=32/64], [if 64, look in /lib64 on hybrid systems]),
[if test "x$with_libarchive_bits" = "x32" ; then
st_lib_archive_LIB=lib
elif test "x$with_libarchive_bits" = "x64" ; then
st_lib_archive_LIB=lib64
else
AC_MSG_ERROR([the argument must be either 32 or 64])
fi],
[st_lib_archive_LIB=lib])
AC_MSG_RESULT($st_lib_archive_LIB)
#
# Save the environment before verifying libarchive availability
#
st_lib_archive_SAVECPPFLAGS="$CPPFLAGS"
st_lib_archive_SAVELDFLAGS="$LDFLAGS"
AC_LANG_SAVE
AC_LANG_C
if test "x$st_lib_archive_LOCATION" = "xdefined" ; then
CPPFLAGS="-I$st_lib_archive_DIR/include $st_lib_archive_SAVECPPFLAGS"
LDFLAGS="-L$st_lib_archive_DIR/$st_lib_archive_LIB $st_lib_archive_SAVELDFLAGS"
AC_CHECK_LIB(archive, archive_read_new, [st_lib_archive_found_lib=yes], [st_lib_archive_found_lib=no])
AC_CHECK_HEADER(archive.h, [st_lib_archive_found_hdr=yes], [st_lib_archive_found_hdr=no])
if test "x$st_lib_archive_found_lib" = "xyes" && test "x$st_lib_archive_found_hdr" = "xyes"; then
LIBARCHIVE_CPPFLAGS="-I$dir/include"
LIBARCHIVE_LDFLAGS="-L$dir/$st_lib_archive_LIB"
else
AC_MSG_ERROR([could not find libarchive in the requested location])
fi
else
#
# These are the common install directories for Linux, FreeBSD, Solaris, and Mac.
#
for dir in /usr /usr/local /usr/sfw /opt/csw /opt/local /sw
do
if test -d "$dir" ; then
CPPFLAGS="-I$dir/include $st_lib_archive_SAVECPPFLAGS"
LDFLAGS="-L$dir/$st_lib_archive_LIB $st_lib_archive_SAVELDFLAGS"
AC_CHECK_LIB(archive, archive_read_new, [st_lib_archive_found_lib=yes], [st_lib_archive_found_lib=no])
AC_CHECK_HEADER(archive.h, [st_lib_archive_found_hdr=yes], [st_lib_archive_found_hdr=no])
if test "x$st_lib_archive_found_lib" = "xyes" && test "x$st_lib_archive_found_hdr" = "xyes"; then
LIBARCHIVE_CPPFLAGS="-I$dir/include"
LIBARCHIVE_LDFLAGS="-L$dir/$st_lib_archive_LIB"
break
fi
fi
done
fi
if test "x$st_lib_archive_found_hdr" = "xyes" && test "x$st_lib_archive_found_lib" = "xyes" ; then
LIBARCHIVE_LIBS="-larchive"
AC_DEFINE([HAVE_LIBARCHIVE], [1], [Defined to 1 if libarchive is available for use.])
AC_SUBST(LIBARCHIVE_LIBS)
AC_SUBST(LIBARCHIVE_CPPFLAGS)
AC_SUBST(LIBARCHIVE_LDFLAGS)
fi
#
# Restore the environment now that we're done.
#
AC_LANG_RESTORE
CPPFLAGS="$st_lib_archive_SAVECPPFLAGS"
LDFLAGS="$st_lib_archive_SAVELDFLAGS"
else
AC_MSG_RESULT([no])
fi
AM_CONDITIONAL(LIBARCHIVE, test "x$st_lib_archive_found_lib" = "xyes" && test "x$st_lib_archive_found_hdr" = "xyes")
])

View File

@ -0,0 +1,136 @@
ODP: [Bug-tar] GNU tar, star and BSD tar speed comparison +new script
Jan Psota
Thu, 25 Oct 2007 06:51:13 -0700
Latest TCP script at the bottom (3180 bytes).
4 tests: 64bit dual core Athlon tmpfs / disk (reiserfs) - 60MB/s,
32bit Athlon tmpfs / disk (reiserfs) - 55MB/s
Both machines were idle -- used for testing only.
Tarball and extracted files were on different physical devices.
Test data: linux 2.6.22/3 kernel sources for memory operations,
for the other data average file size should bring enough info.
2 x [...] processor means 1 processor with 2 cores (2 entries in cpuinfo).
Archive format is set to pax (Joerg).
Let's end with it. I only wanted to send You a new version of TCP script :-).
--
Jan Psota
TCP, version 2007-10-25
Linux 2.6.22-suspend2-r2 / Gentoo Base System release 2.0.0_rc5
2012MB of memory, 2 x AMD Athlon(tm) 64 X2 Dual Core Processor 4200+ 2211.348
512 KB 4426.24 bmips
gcc (GCC) 4.2.2 (Gentoo 4.2.2 p1.0)
CFLAGS="-O2 -march=k8 -pipe"
bsdtar: bsdtar 2.3.4 - libarchive 2.3.4
gnutar: tar (GNU tar) 1.19
star: star: star 1.5a85 (x86_64-unknown-linux-gnu)
best time of 5 repetitions,
src=linux-2.6.23, 291M in 23867 files, avg 13KB/file,
archive=/tmp/tcp.tar, extract to /tmp/tcptmp
program operation real user system %CPU speed
bsdtar create 0.764 0.232 0.532 99.96 370308 KB/s
gnutar create 0.743 0.200 0.512 95.87 380775 KB/s
star create 0.587 0.040 0.820 100.00 441247 KB/s
bsdtar list 0.164 0.096 0.068 99.84 1579341 KB/s
gnutar list 0.218 0.064 0.152 98.92 1188128 KB/s
star list 0.359 0.044 0.240 79.09 721481 KB/s
bsdtar extract 0.733 0.200 0.504 96.02 353358 KB/s
gnutar extract 0.625 0.092 0.508 96.02 414419 KB/s
star extract 0.875 0.096 0.980 100.00 296013 KB/s
bsdtar compare 0.001 0.000 0.000 0.00 259012000 KB/s
gnutar compare 0.719 0.288 0.400 95.66 360239 KB/s
star compare 0.695 0.224 0.636 100.00 372679 KB/s
[...]
best time of 3 repetitions,
src=/home, 3.2G in 7447 files, avg 554KB/file,
archive=/var/tcp.tar, extract to /mnt/a/tcptmp
program operation real user system %CPU speed
bsdtar create 184.680 0.552 13.365 7.53 17958 KB/s
gnutar create 159.240 0.256 12.417 7.95 20827 KB/s
star create 181.779 0.140 14.789 8.21 18203 KB/s
bsdtar list 0.053 0.032 0.016 91.41 62435471 KB/s
gnutar list 56.535 0.136 3.764 6.89 58531 KB/s
star list 56.652 0.080 5.236 9.38 58410 KB/s
bsdtar extract 78.914 0.820 15.149 20.23 41932 KB/s
gnutar extract 78.480 0.196 14.197 18.33 42164 KB/s
star extract 79.439 0.132 12.973 16.49 41655 KB/s
bsdtar compare 0.001 0.000 0.000 0.00 3309080000 KB/s
gnutar compare 61.771 3.464 8.905 20.02 53570 KB/s
star compare 57.561 1.728 9.897 20.19 57488 KB/s
Linux 2.6.22-suspend2-smp / Gentoo Base System release 2.0.0_rc5
504MB of memory, 1 x AMD Athlon(tm) Processor 1500.033 256 KB 3002.55 bmips
gcc (GCC) 4.2.2 (Gentoo 4.2.2 p1.0)
CFLAGS="-O2 -march=athlon-xp -mfpmath=sse -frename-registers -pipe"
bsdtar: bsdtar 2.3.4 - libarchive 2.3.4
gnutar: tar (GNU tar) 1.19
star: star: star 1.5a85 (i686-pc-linux-gnu)
best time of 3 repetitions,
src=/usr/src/linux-2.6.22-suspend2/drivers, 119M in 5900 files,
avg 21KB/file, archive=/tmp/tcp.tar, extract to /tmp/tcptmp
program operation real user system %CPU speed
bsdtar create 1.329 0.192 1.132 99.63 89784 KB/s
gnutar create 1.223 0.124 1.092 99.46 97566 KB/s
star create 1.848 0.036 1.708 94.36 61372 KB/s
bsdtar list 0.167 0.060 0.108 100.00 679137 KB/s
gnutar list 0.161 0.040 0.124 100.00 704447 KB/s
star list 0.859 0.044 0.716 88.51 132032 KB/s
bsdtar extract 1.186 0.172 1.012 99.87 95629 KB/s
gnutar extract 1.064 0.056 1.004 99.63 106593 KB/s
star extract 1.920 0.088 1.724 94.40 59070 KB/s
bsdtar compare 0.002 0.000 0.000 0.00 56708000 KB/s
gnutar compare 0.925 0.232 0.692 99.90 122611 KB/s
star compare 1.569 0.376 1.096 93.79 72285 KB/s
[...]
best time of 3 repetitions,
src=/home/jasiu, 2.1G in 8416 files, avg 277KB/file,
archive=/home/j2/tcp.tar, extract to /mnt/a/tar/tcptmp
program operation real user system %CPU speed
bsdtar create 182.171 1.692 29.130 16.91 11584 KB/s
gnutar create 174.999 0.632 27.450 16.04 12059 KB/s
star create 180.004 0.360 41.795 23.41 11677 KB/s
bsdtar list 0.214 0.076 0.136 99.04 9822294 KB/s
gnutar list 0.210 0.076 0.136 100.00 10009385 KB/s
star list 43.462 0.148 18.109 42.00 48363 KB/s
bsdtar extract 94.912 4.476 31.574 37.98 22146 KB/s
gnutar extract 94.657 0.396 29.462 31.54 22206 KB/s
star extract 100.814 0.400 39.906 39.98 20849 KB/s
bsdtar compare 0.003 0.000 0.004 100.00 700657000 KB/s
gnutar compare 80.174 3.932 20.365 30.30 26217 KB/s
star compare 73.911 8.341 27.670 48.72 28439 KB/s
=============================================================
Note by Tim Kientzle: The "bsdtar compare" results here are
invalid since bsdtar does not support that operation.
For the list numbers, note that libarchive automatically optimizes
list operations on uncompressed tar archives on disk by using lseek()
to skip over the bodies of entries. GNU tar added an option to
provide the same feature.
The biggest problem with these tests is that they only
cover uncompressed archives stored on disk. The results for
compressed archives and/or archives stored on tape are
likely quite different.

110
contrib/psota-benchmark/tcp.sh Executable file
View File

@ -0,0 +1,110 @@
#!/bin/sh
# tar comparison program
# 2007-10-25 Jan Psota
n=3 # number of repetitions
TAR="bsdtar gnutar star" # Tape archivers to compare
OPT=("" "--seek" "-no-fsync")
pax="--format=pax" # comment out for defaults
OPN=(create list extract compare) # operations
version="2007-10-25"
TIMEFORMAT=$'%R\t%U\t%S\t%P'
LC_ALL=C
test $# -ge 2 || {
echo -e "usage:\t$0 source_dir where_to_place_archive
[where_to_extract_it]
TCP, version $version
TCP stands for Tar Comparison Program here.
It currently compares: BSD tar (bsdtar), GNU tar (gnutar) and star in archive
creation, listing, extraction and archive-to-extracted comparison.
Tcp prints out best time of n=$n repetitions.
Tcp creates temporary archive named tcp.tar with $pax and some native
(--seek/-no-fsync) options and extracts it to [\$3]/tcptmp/.
If unset, third argument defaults to [\$2].
After normal exit tcp removes tarball and extracted files.
Tcp does not check filesystems destination directories are on for free space,
so make sure there is enough space (a bit more than source_dir uses) for both:
archive and extracted files.
Do not use white space in arguments.
Jan Psota, $version"
exit 0
}
src=$1
dst=$2/tcp.tar
dst_path=${3:-$2}/tcptmp
test -e $dst -o -e /tmp/tcp \
&& { echo "$dst or /tmp/tcp exists, exiting"; exit 1; }
mkdir $dst_path || exit 2
use_times ()
{
awk -F"\t" -vN=$n -vL="`du -k $dst`" -vOFS="\t" -vORS="" '
{ if (NF==4) { printf "\t%s\t%10.1d KB/s\n", $0, ($1+0>0 ?
(L+0)/($1+0) : 0) } }' \
/tmp/tcp | sort | head -1
> /tmp/tcp
}
test -d $src || { echo "'$src' is not a directory"; exit 3; }
# system information: type, release, memory, cpu(s), compiler and flags
echo -e "TCP, version $version\n"`uname -sr`" / "`head -1 /etc/*-release`
free -m | awk '/^Mem/ { printf "%dMB of memory, ", $2 }'
test -e /proc/cpuinfo \
&& awk -F: '/name|cache size|MHz|mips/ { if (!a) b=b $2 }
/^$/ { a++ } END { print a" x"b" bmips" }' /proc/cpuinfo
test -e /etc/gentoo-release \
&& gcc --version | head -1 && grep ^CFLAGS /etc/make.conf
# tar versions
t=
echo
for tar in $TAR; do
if which $tar &> /dev/null; then
t="$t $tar";
echo -ne "$tar:\t"; $tar --version | head -1;
fi
done
TAR="$t"
echo -e "\nbest time of $n repetitions,\n"\
" src=$src, "\
`du -sh $src | awk '{print $1}'`" in "`find $src | wc -l`" files, "\
"avg "$((`du -sk $src | awk '{print $1}'`/`find $src -type f | wc -l`))"KB/file,\n"\
" archive=$dst, extract to $dst_path"
echo -e "program\toperation\treal\tuser\tsystem\t%CPU\t speed"
> /tmp/tcp
let op_num=0
for op in "cf $dst $pax -C $src ." "tf $dst" "xf $dst -C $dst_path" \
"f $dst -C $dst_path --diff"; do
let tar_num=0
for tar in $TAR; do
echo -en "$tar\t${OPN[op_num]}\t"
for ((i=1; i<=$n; i++)); do
echo $op | grep -q ^cf && rm -f $dst
echo $op | grep -q ^xf &&
{ chmod -R u+w $dst_path
rm -rf $dst_path; mkdir $dst_path; }
sync
if echo $op | grep -q ^f; then # op == compare
time $tar $op ${OPT[$tar_num]} > /dev/null
else # op in (create | list | extract)
time $tar $op ${OPT[$tar_num]} > /dev/null \
|| break 3
fi 2>> /tmp/tcp
done
use_times
let tar_num++
done
let op_num++
echo
done
rm -rf $dst_path $dst
echo
cat /tmp/tcp
rm -f /tmp/tcp

14
contrib/shar/Makefile Normal file
View File

@ -0,0 +1,14 @@
# $FreeBSD$
PROG= shar
SRCS= shar.c tree.c
WARNS?= 6
DPADD= ${LIBARCHIVE}
LDADD= -larchive
LINKS= ${BINDIR}/shar
MLINKS= shar.1
.include <bsd.prog.mk>

128
contrib/shar/shar.1 Normal file
View File

@ -0,0 +1,128 @@
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. 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.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 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.
.\"
.\" @(#)shar.1 8.1 (Berkeley) 6/6/93
.\" $FreeBSD$
.\"
.Dd April 17, 2008
.Dt SHAR 1
.Os
.Sh NAME
.Nm shar
.Nd create a shell archive of files
.Sh SYNOPSIS
.Nm
.Op Fl br
.Op Fl o Ar archive-file
.Ar
.Sh DESCRIPTION
The
.Nm
command writes a
.Xr sh 1
shell script which will recreate the file hierarchy specified by the command
line operands.
.Pp
The
.Nm
command is normally used for distributing files by
.Xr ftp 1
or
.Xr mail 1 .
.Pp
The following options are available:
.Bl -tag -width indent
.It Fl b
Use an alternative binary format. Content of files will be uuencoded.
This option should be used to archive binary files correctly.
In this mode also file permissions will be stored to the archive.
uudecode(1) is needed to extract archives created with this option.
.It Fl o Ar archive-file
Redirect output to
.Ar archive-file .
.It Fl r
If
.Ar file
given on command line is a directory the entire subtree will be archived.
Symbolic links given on command line are followed. Other symbolic links will
be archived as such.
.El
.Sh EXAMPLES
To create a shell archive of the program
.Xr ls 1
and mail it to Rick:
.Bd -literal -offset indent
cd ls
shar -r . \&| mail -s "ls source" rick
.Ed
.Pp
To recreate the program directory:
.Bd -literal -offset indent
mkdir ls
cd ls
\&...
<delete header lines and examine mailed archive>
\&...
sh archive
.Ed
.Sh SEE ALSO
.Xr compress 1 ,
.Xr mail 1 ,
.Xr tar 1 ,
.Xr uuencode 1 ,
.Xr uuencode 5
.Sh HISTORY
The
.Nm
command appeared in
.Bx 4.4 .
This is a re-implementation based on the libarchive(3) library.
.Sh BUGS
The
.Nm
command makes no provisions for hard links.
.Pp
Files containing magic characters or files without a newline ('\\n') as the
last character are not handled correctly with the default format. Use the -b
option for binary files.
.Pp
It is easy to insert trojan horses into
.Nm
files.
It is strongly recommended that all shell archive files be examined
before running them through
.Xr sh 1 .
Archives produced using this implementation of
.Nm
may be easily examined with the command:
.Bd -literal -offset indent
egrep -v '^[X#]' shar.file
.Ed

314
contrib/shar/shar.c Normal file
View File

@ -0,0 +1,314 @@
/*-
* Copyright (c) 2008 Jaakko Heinonen
* 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 <sys/cdefs.h>
#ifdef __FBSDID
__FBSDID("$FreeBSD$");
#endif
#include <sys/stat.h>
#include <sys/types.h>
#include <archive.h>
#include <archive_entry.h>
#include <assert.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
#include "tree.h"
/* command line options */
static int b_opt; /* use alternative shar binary format */
static int r_opt; /* recurse into subdirectories */
static char *o_arg; /* output file name */
static void
usage(void)
{
fprintf(stderr, "Usage: shar [-br] [-o filename] file ...\n");
exit(EX_USAGE);
}
/*
* Initialize archive structure and create a shar archive.
*/
static struct archive *
shar_create(void)
{
struct archive *a;
if ((a = archive_write_new()) == NULL)
errx(EXIT_FAILURE, "%s", archive_error_string(a));
if (b_opt)
archive_write_set_format_shar_dump(a);
else
archive_write_set_format_shar(a);
archive_write_set_compression_none(a);
if (archive_write_open_filename(a, o_arg) != ARCHIVE_OK)
errx(EX_CANTCREAT, "%s", archive_error_string(a));
return (a);
}
/* buffer for file data */
static char buffer[32768];
/*
* Write file data to an archive entry.
*/
static int
shar_write_entry_data(struct archive *a, const int fd)
{
ssize_t bytes_read, bytes_written;
assert(a != NULL);
assert(fd >= 0);
bytes_read = read(fd, buffer, sizeof(buffer));
while (bytes_read != 0) {
if (bytes_read < 0) {
archive_set_error(a, errno, "Read failed");
return (ARCHIVE_WARN);
}
bytes_written = archive_write_data(a, buffer, bytes_read);
if (bytes_written < 0)
return (ARCHIVE_WARN);
bytes_read = read(fd, buffer, sizeof(buffer));
}
return (ARCHIVE_OK);
}
/*
* Write a file to the archive. We have special handling for symbolic links.
*/
static int
shar_write_entry(struct archive *a, const char *pathname, const char *accpath,
const struct stat *st)
{
struct archive_entry *entry;
int fd = -1;
int ret = ARCHIVE_OK;
assert(a != NULL);
assert(pathname != NULL);
assert(accpath != NULL);
assert(st != NULL);
entry = archive_entry_new();
if (S_ISREG(st->st_mode) && st->st_size > 0) {
/* regular file */
if ((fd = open(accpath, O_RDONLY)) == -1) {
warn("%s", accpath);
ret = ARCHIVE_WARN;
goto out;
}
} else if (S_ISLNK(st->st_mode)) {
/* symbolic link */
char lnkbuff[PATH_MAX + 1];
int lnklen;
if ((lnklen = readlink(accpath, lnkbuff, PATH_MAX)) == -1) {
warn("%s", accpath);
ret = ARCHIVE_WARN;
goto out;
}
lnkbuff[lnklen] = '\0';
archive_entry_set_symlink(entry, lnkbuff);
}
archive_entry_copy_stat(entry, st);
archive_entry_set_pathname(entry, pathname);
if (!S_ISREG(st->st_mode) || st->st_size == 0)
archive_entry_set_size(entry, 0);
if (archive_write_header(a, entry) != ARCHIVE_OK) {
warnx("%s: %s", pathname, archive_error_string(a));
ret = ARCHIVE_WARN;
goto out;
}
if (fd >= 0) {
if ((ret = shar_write_entry_data(a, fd)) != ARCHIVE_OK)
warnx("%s: %s", accpath, archive_error_string(a));
}
out:
archive_entry_free(entry);
if (fd >= 0)
close(fd);
return (ret);
}
/*
* Write singe path to the archive. The path can be a regular file, directory
* or device. Symbolic links are followed.
*/
static int
shar_write_path(struct archive *a, const char *pathname)
{
struct stat st;
assert(a != NULL);
assert(pathname != NULL);
if ((stat(pathname, &st)) == -1) {
warn("%s", pathname);
return (ARCHIVE_WARN);
}
return (shar_write_entry(a, pathname, pathname, &st));
}
/*
* Write tree to the archive. If pathname is a symbolic link it will be
* followed. Other symbolic links are stored as such to the archive.
*/
static int
shar_write_tree(struct archive *a, const char *pathname)
{
struct tree *t;
const struct stat *lst, *st;
int error = 0;
int tree_ret;
int first;
assert(a != NULL);
assert(pathname != NULL);
t = tree_open(pathname);
for (first = 1; (tree_ret = tree_next(t)); first = 0) {
if (tree_ret == TREE_ERROR_DIR) {
warnx("%s: %s", tree_current_path(t),
strerror(tree_errno(t)));
error = 1;
continue;
} else if (tree_ret != TREE_REGULAR)
continue;
if ((lst = tree_current_lstat(t)) == NULL) {
warn("%s", tree_current_path(t));
error = 1;
continue;
}
/*
* If the symlink was given on command line then
* follow it rather than write it as symlink.
*/
if (first && S_ISLNK(lst->st_mode)) {
if ((st = tree_current_stat(t)) == NULL) {
warn("%s", tree_current_path(t));
error = 1;
continue;
}
} else
st = lst;
if (shar_write_entry(a, tree_current_path(t),
tree_current_access_path(t), st) != ARCHIVE_OK)
error = 1;
tree_descend(t);
}
tree_close(t);
return ((error != 0) ? ARCHIVE_WARN : ARCHIVE_OK);
}
/*
* Create a shar archive and write files/trees into it.
*/
static int
shar_write(char **fn, size_t nfn)
{
struct archive *a;
size_t i;
int error = 0;
assert(fn != NULL);
assert(nfn > 0);
a = shar_create();
for (i = 0; i < nfn; i++) {
if (r_opt) {
if (shar_write_tree(a, fn[i]) != ARCHIVE_OK)
error = 1;
} else {
if (shar_write_path(a, fn[i]) != ARCHIVE_OK)
error = 1;
}
}
if (archive_write_free(a) != ARCHIVE_OK)
errx(EXIT_FAILURE, "%s", archive_error_string(a));
if (error != 0)
warnx("Error exit delayed from previous errors.");
return (error);
}
int
main(int argc, char **argv)
{
int opt;
while ((opt = getopt(argc, argv, "bro:")) != -1) {
switch (opt) {
case 'b':
b_opt = 1;
break;
case 'o':
o_arg = optarg;
break;
case 'r':
r_opt = 1;
break;
default:
usage();
/* NOTREACHED */
}
}
argc -= optind;
argv += optind;
if(argc < 1)
usage();
if (shar_write(argv, argc) != 0)
exit(EXIT_FAILURE);
else
exit(EXIT_SUCCESS);
/* NOTREACHED */
}

542
contrib/shar/tree.c Normal file
View File

@ -0,0 +1,542 @@
/*-
* 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 is a new directory-walking system that addresses a number
* of problems I've had with fts(3). In particular, it has no
* pathname-length limits (other than the size of 'int'), handles
* deep logical traversals, uses considerably less memory, and has
* an opaque interface (easier to modify in the future).
*
* Internally, it keeps a single list of "tree_entry" items that
* represent filesystem objects that require further attention.
* Non-directories are not kept in memory: they are pulled from
* readdir(), returned to the client, then freed as soon as possible.
* Any directory entry to be traversed gets pushed onto the stack.
*
* There is surprisingly little information that needs to be kept for
* each item on the stack. Just the name, depth (represented here as the
* string length of the parent directory's pathname), and some markers
* indicating how to get back to the parent (via chdir("..") for a
* regular dir or via fchdir(2) for a symlink).
*/
#include "tree_config.h"
__FBSDID("$FreeBSD$");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.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 "tree.h"
/*
* TODO:
* 1) Loop checking.
* 3) Arbitrary logical traversals by closing/reopening intermediate fds.
*/
struct tree_entry {
struct tree_entry *next;
struct tree_entry *parent;
char *name;
size_t dirname_length;
dev_t dev;
ino_t ino;
int fd;
int flags;
};
/* Definitions for tree_entry.flags bitmap. */
#define isDir 1 /* This entry is a regular directory. */
#define isDirLink 2 /* This entry is a symbolic link to a directory. */
#define needsPreVisit 4 /* This entry needs to be previsited. */
#define needsPostVisit 8 /* This entry needs to be postvisited. */
/*
* Local data for this package.
*/
struct tree {
struct tree_entry *stack;
struct tree_entry *current;
DIR *d;
int initialDirFd;
int flags;
int visit_type;
int tree_errno; /* Error code from last failed operation. */
char *buff;
const char *basename;
size_t buff_length;
size_t path_length;
size_t dirname_length;
int depth;
int openCount;
int maxOpenCount;
struct stat lst;
struct stat st;
};
/* Definitions for tree.flags bitmap. */
#define needsReturn 8 /* Marks first entry as not having been returned yet. */
#define hasStat 16 /* The st entry is set. */
#define hasLstat 32 /* The lst entry is set. */
#ifdef HAVE_DIRENT_D_NAMLEN
/* BSD extension; avoids need for a strlen() call. */
#define D_NAMELEN(dp) (dp)->d_namlen
#else
#define D_NAMELEN(dp) (strlen((dp)->d_name))
#endif
#if 0
#include <stdio.h>
void
tree_dump(struct tree *t, FILE *out)
{
struct tree_entry *te;
fprintf(out, "\tdepth: %d\n", t->depth);
fprintf(out, "\tbuff: %s\n", t->buff);
fprintf(out, "\tpwd: "); fflush(stdout); system("pwd");
fprintf(out, "\taccess: %s\n", t->basename);
fprintf(out, "\tstack:\n");
for (te = t->stack; te != NULL; te = te->next) {
fprintf(out, "\t\tte->name: %s%s%s\n", te->name,
te->flags & needsPreVisit ? "" : " *",
t->current == te ? " (current)" : "");
}
}
#endif
/*
* Add a directory path to the current stack.
*/
static void
tree_push(struct tree *t, const char *path)
{
struct tree_entry *te;
te = malloc(sizeof(*te));
memset(te, 0, sizeof(*te));
te->next = t->stack;
t->stack = te;
te->fd = -1;
te->name = strdup(path);
te->flags = needsPreVisit | needsPostVisit;
te->dirname_length = t->dirname_length;
}
/*
* Append a name to the current path.
*/
static void
tree_append(struct tree *t, const char *name, size_t name_length)
{
char *p;
if (t->buff != NULL)
t->buff[t->dirname_length] = '\0';
/* Strip trailing '/' from name, unless entire name is "/". */
while (name_length > 1 && name[name_length - 1] == '/')
name_length--;
/* Resize pathname buffer as needed. */
while (name_length + 1 + t->dirname_length >= t->buff_length) {
t->buff_length *= 2;
if (t->buff_length < 1024)
t->buff_length = 1024;
t->buff = realloc(t->buff, t->buff_length);
}
p = t->buff + t->dirname_length;
t->path_length = t->dirname_length + name_length;
/* Add a separating '/' if it's needed. */
if (t->dirname_length > 0 && p[-1] != '/') {
*p++ = '/';
t->path_length ++;
}
strncpy(p, name, name_length);
p[name_length] = '\0';
t->basename = p;
}
/*
* Open a directory tree for traversal.
*/
struct tree *
tree_open(const char *path)
{
struct tree *t;
t = malloc(sizeof(*t));
memset(t, 0, sizeof(*t));
tree_append(t, path, strlen(path));
t->initialDirFd = open(".", O_RDONLY);
/*
* During most of the traversal, items are set up and then
* returned immediately from tree_next(). That doesn't work
* for the very first entry, so we set a flag for this special
* case.
*/
t->flags = needsReturn;
return (t);
}
/*
* We've finished a directory; ascend back to the parent.
*/
static void
tree_ascend(struct tree *t)
{
struct tree_entry *te;
te = t->stack;
t->depth--;
if (te->flags & isDirLink) {
fchdir(te->fd);
close(te->fd);
t->openCount--;
} else {
chdir("..");
}
}
/*
* Pop the working stack.
*/
static void
tree_pop(struct tree *t)
{
struct tree_entry *te;
t->buff[t->dirname_length] = '\0';
if (t->stack == t->current && t->current != NULL)
t->current = t->current->parent;
te = t->stack;
t->stack = te->next;
t->dirname_length = te->dirname_length;
t->basename = t->buff + t->dirname_length;
/* Special case: starting dir doesn't skip leading '/'. */
if (t->dirname_length > 0)
t->basename++;
free(te->name);
free(te);
}
/*
* Get the next item in the tree traversal.
*/
int
tree_next(struct tree *t)
{
struct dirent *de = NULL;
/* Handle the startup case by returning the initial entry. */
if (t->flags & needsReturn) {
t->flags &= ~needsReturn;
return (t->visit_type = TREE_REGULAR);
}
while (t->stack != NULL) {
/* If there's an open dir, get the next entry from there. */
while (t->d != NULL) {
de = readdir(t->d);
if (de == NULL) {
closedir(t->d);
t->d = NULL;
} else if (de->d_name[0] == '.'
&& de->d_name[1] == '\0') {
/* Skip '.' */
} else if (de->d_name[0] == '.'
&& de->d_name[1] == '.'
&& de->d_name[2] == '\0') {
/* Skip '..' */
} else {
/*
* Append the path to the current path
* and return it.
*/
tree_append(t, de->d_name, D_NAMELEN(de));
t->flags &= ~hasLstat;
t->flags &= ~hasStat;
return (t->visit_type = TREE_REGULAR);
}
}
/* If the current dir needs to be visited, set it up. */
if (t->stack->flags & needsPreVisit) {
t->current = t->stack;
tree_append(t, t->stack->name, strlen(t->stack->name));
t->stack->flags &= ~needsPreVisit;
/* If it is a link, set up fd for the ascent. */
if (t->stack->flags & isDirLink) {
t->stack->fd = open(".", O_RDONLY);
t->openCount++;
if (t->openCount > t->maxOpenCount)
t->maxOpenCount = t->openCount;
}
t->dirname_length = t->path_length;
if (chdir(t->stack->name) != 0) {
/* chdir() failed; return error */
tree_pop(t);
t->tree_errno = errno;
return (t->visit_type = TREE_ERROR_DIR);
}
t->depth++;
t->d = opendir(".");
if (t->d == NULL) {
tree_ascend(t); /* Undo "chdir" */
tree_pop(t);
t->tree_errno = errno;
return (t->visit_type = TREE_ERROR_DIR);
}
t->flags &= ~hasLstat;
t->flags &= ~hasStat;
t->basename = ".";
return (t->visit_type = TREE_POSTDESCENT);
}
/* We've done everything necessary for the top stack entry. */
if (t->stack->flags & needsPostVisit) {
tree_ascend(t);
tree_pop(t);
t->flags &= ~hasLstat;
t->flags &= ~hasStat;
return (t->visit_type = TREE_POSTASCENT);
}
}
return (t->visit_type = 0);
}
/*
* Return error code.
*/
int
tree_errno(struct tree *t)
{
return (t->tree_errno);
}
/*
* Called by the client to mark the directory just returned from
* tree_next() as needing to be visited.
*/
void
tree_descend(struct tree *t)
{
if (t->visit_type != TREE_REGULAR)
return;
if (tree_current_is_physical_dir(t)) {
tree_push(t, t->basename);
t->stack->flags |= isDir;
} else if (tree_current_is_dir(t)) {
tree_push(t, t->basename);
t->stack->flags |= isDirLink;
}
}
/*
* Get the stat() data for the entry just returned from tree_next().
*/
const struct stat *
tree_current_stat(struct tree *t)
{
if (!(t->flags & hasStat)) {
if (stat(t->basename, &t->st) != 0)
return NULL;
t->flags |= hasStat;
}
return (&t->st);
}
/*
* Get the lstat() data for the entry just returned from tree_next().
*/
const struct stat *
tree_current_lstat(struct tree *t)
{
if (!(t->flags & hasLstat)) {
if (lstat(t->basename, &t->lst) != 0)
return NULL;
t->flags |= hasLstat;
}
return (&t->lst);
}
/*
* Test whether current entry is a dir or link to a dir.
*/
int
tree_current_is_dir(struct tree *t)
{
const struct stat *st;
/*
* If we already have lstat() info, then try some
* cheap tests to determine if this is a dir.
*/
if (t->flags & hasLstat) {
/* If lstat() says it's a dir, it must be a dir. */
if (S_ISDIR(tree_current_lstat(t)->st_mode))
return 1;
/* Not a dir; might be a link to a dir. */
/* If it's not a link, then it's not a link to a dir. */
if (!S_ISLNK(tree_current_lstat(t)->st_mode))
return 0;
/*
* It's a link, but we don't know what it's a link to,
* so we'll have to use stat().
*/
}
st = tree_current_stat(t);
/* If we can't stat it, it's not a dir. */
if (st == NULL)
return 0;
/* Use the definitive test. Hopefully this is cached. */
return (S_ISDIR(st->st_mode));
}
/*
* Test whether current entry is a physical directory. Usually, we
* already have at least one of stat() or lstat() in memory, so we
* use tricks to try to avoid an extra trip to the disk.
*/
int
tree_current_is_physical_dir(struct tree *t)
{
const struct stat *st;
/*
* If stat() says it isn't a dir, then it's not a dir.
* If stat() data is cached, this check is free, so do it first.
*/
if ((t->flags & hasStat)
&& (!S_ISDIR(tree_current_stat(t)->st_mode)))
return 0;
/*
* Either stat() said it was a dir (in which case, we have
* to determine whether it's really a link to a dir) or
* stat() info wasn't available. So we use lstat(), which
* hopefully is already cached.
*/
st = tree_current_lstat(t);
/* If we can't stat it, it's not a dir. */
if (st == NULL)
return 0;
/* Use the definitive test. Hopefully this is cached. */
return (S_ISDIR(st->st_mode));
}
/*
* Test whether current entry is a symbolic link.
*/
int
tree_current_is_physical_link(struct tree *t)
{
const struct stat *st = tree_current_lstat(t);
if (st == NULL)
return 0;
return (S_ISLNK(st->st_mode));
}
/*
* Return the access path for the entry just returned from tree_next().
*/
const char *
tree_current_access_path(struct tree *t)
{
return (t->basename);
}
/*
* Return the full path for the entry just returned from tree_next().
*/
const char *
tree_current_path(struct tree *t)
{
return (t->buff);
}
/*
* Return the length of the path for the entry just returned from tree_next().
*/
size_t
tree_current_pathlen(struct tree *t)
{
return (t->path_length);
}
/*
* Return the nesting depth of the entry just returned from tree_next().
*/
int
tree_current_depth(struct tree *t)
{
return (t->depth);
}
/*
* Terminate the traversal and release any resources.
*/
void
tree_close(struct tree *t)
{
/* Release anything remaining in the stack. */
while (t->stack != NULL)
tree_pop(t);
if (t->buff)
free(t->buff);
/* chdir() back to where we started. */
if (t->initialDirFd >= 0) {
fchdir(t->initialDirFd);
close(t->initialDirFd);
t->initialDirFd = -1;
}
free(t);
}

115
contrib/shar/tree.h Normal file
View File

@ -0,0 +1,115 @@
/*-
* 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$
*/
/*-
* A set of routines for traversing directory trees.
* Similar in concept to the fts library, but with a few
* important differences:
* * Uses less memory. In particular, fts stores an entire directory
* in memory at a time. This package only keeps enough subdirectory
* information in memory to track the traversal. Information
* about non-directories is discarded as soon as possible.
* * Supports very deep logical traversals. The fts package
* uses "non-chdir" approach for logical traversals. This
* package does use a chdir approach for logical traversals
* and can therefore handle pathnames much longer than
* PATH_MAX.
* * Supports deep physical traversals "out of the box."
* Due to the memory optimizations above, there's no need to
* limit dir names to 32k.
*/
#include <sys/stat.h>
#include <stdio.h>
struct tree;
/* Initiate/terminate a tree traversal. */
struct tree *tree_open(const char * /* pathname */);
void tree_close(struct tree *);
/*
* tree_next() returns Zero if there is no next entry, non-zero if there is.
* Note that directories are potentially visited three times. The first
* time as "regular" file. If tree_descend() is invoked at that time,
* the directory is added to a work list and will be visited two more
* times: once just after descending into the directory and again
* just after ascending back to the parent.
*
* TREE_ERROR is returned if the descent failed (because the
* directory couldn't be opened, for instance). This is returned
* instead of TREE_PREVISIT/TREE_POSTVISIT.
*/
#define TREE_REGULAR 1
#define TREE_POSTDESCENT 2
#define TREE_POSTASCENT 3
#define TREE_ERROR_DIR -1
int tree_next(struct tree *);
int tree_errno(struct tree *);
/*
* Request that current entry be visited. If you invoke it on every
* directory, you'll get a physical traversal. This is ignored if the
* current entry isn't a directory or a link to a directory. So, if
* you invoke this on every returned path, you'll get a full logical
* traversal.
*/
void tree_descend(struct tree *);
/*
* Return information about the current entry.
*/
int tree_current_depth(struct tree *);
/*
* The current full pathname, length of the full pathname,
* and a name that can be used to access the file.
* Because tree does use chdir extensively, the access path is
* almost never the same as the full current path.
*/
const char *tree_current_path(struct tree *);
size_t tree_current_pathlen(struct tree *);
const char *tree_current_access_path(struct tree *);
/*
* Request the lstat() or stat() data for the current path. Since the
* tree package needs to do some of this anyway, and caches the
* results, you should take advantage of it here if you need it rather
* than make a redundant stat() or lstat() call of your own.
*/
const struct stat *tree_current_stat(struct tree *);
const struct stat *tree_current_lstat(struct tree *);
/* The following tests may use mechanisms much faster than stat()/lstat(). */
/* "is_physical_dir" is equivalent to S_ISDIR(tree_current_lstat()->st_mode) */
int tree_current_is_physical_dir(struct tree *);
/* "is_physical_link" is equivalent to S_ISLNK(tree_current_lstat()->st_mode) */
int tree_current_is_physical_link(struct tree *);
/* "is_dir" is equivalent to S_ISDIR(tree_current_stat()->st_mode) */
int tree_current_is_dir(struct tree *);
/* For testing/debugging: Dump the internal status to the given filehandle. */
void tree_dump(struct tree *, FILE *);

View File

@ -0,0 +1,78 @@
/*-
* 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$
*/
#ifndef TREE_CONFIG_H_INCLUDED
#define TREE_CONFIG_H_INCLUDED
#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"
#elif defined(__FreeBSD__)
/*
* Built-in definitions for FreeBSD.
*/
#define HAVE_DIRENT_D_NAMLEN 1
#define HAVE_DIRENT_H 1
#define HAVE_ERRNO_H 1
#define HAVE_FCNTL_H 1
#define HAVE_LIBARCHIVE 1
#define HAVE_STDLIB_H 1
#define HAVE_STRING_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_UNISTD_H 1
#else
/*
* Warn if there's no platform configuration.
*/
#error Oops: No config.h and no built-in configuration in bsdtar_platform.h.
#endif /* !HAVE_CONFIG_H */
/* No non-FreeBSD platform will have __FBSDID, so just define it here. */
#ifdef __FreeBSD__
#include <sys/cdefs.h> /* For __FBSDID */
#else
/* Just leaving this macro replacement empty leads to a dangling semicolon. */
#define __FBSDID(a) struct _undefined_hack
#endif
#ifdef HAVE_LIBARCHIVE
/* If we're using the platform libarchive, include system headers. */
#include <archive.h>
#include <archive_entry.h>
#else
/* Otherwise, include user headers. */
#include "archive.h"
#include "archive_entry.h"
#endif
#endif /* !TREE_CONFIG_H_INCLUDED */

225
contrib/untar.c Normal file
View File

@ -0,0 +1,225 @@
/*
* "untar" is an extremely simple tar extractor:
* * A single C source file, so it should be easy to compile
* and run on any system with a C compiler.
* * Extremely portable standard C. The only non-ANSI function
* used is mkdir().
* * Reads basic ustar tar archives.
* * Does not require libarchive or any other special library.
*
* To compile: cc -o untar untar.c
*
* Usage: untar <archive>
*
* In particular, this program should be sufficient to extract the
* distribution for libarchive, allowing people to bootstrap
* libarchive on systems that do not already have a tar program.
*
* To unpack libarchive-x.y.z.tar.gz:
* * gunzip libarchive-x.y.z.tar.gz
* * untar libarchive-x.y.z.tar
*
* Written by Tim Kientzle, March 2009.
*
* Released into the public domain.
*/
/* These are all highly standard and portable headers. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* This is for mkdir(); this may need to be changed for some platforms. */
#include <sys/stat.h> /* For mkdir() */
/* Parse an octal number, ignoring leading and trailing nonsense. */
static int
parseoct(const char *p, size_t n)
{
int i = 0;
while ((*p < '0' || *p > '7') && n > 0) {
++p;
--n;
}
while (*p >= '0' && *p <= '7' && n > 0) {
i *= 8;
i += *p - '0';
++p;
--n;
}
return (i);
}
/* Returns true if this is 512 zero bytes. */
static int
is_end_of_archive(const char *p)
{
int n;
for (n = 511; n >= 0; --n)
if (p[n] != '\0')
return (0);
return (1);
}
/* Create a directory, including parent directories as necessary. */
static void
create_dir(char *pathname, int mode)
{
char *p;
int r;
/* Strip trailing '/' */
if (pathname[strlen(pathname) - 1] == '/')
pathname[strlen(pathname) - 1] = '\0';
/* Try creating the directory. */
r = mkdir(pathname, mode);
if (r != 0) {
/* On failure, try creating parent directory. */
p = strrchr(pathname, '/');
if (p != NULL) {
*p = '\0';
create_dir(pathname, 0755);
*p = '/';
r = mkdir(pathname, mode);
}
}
if (r != 0)
fprintf(stderr, "Could not create directory %s\n", pathname);
}
/* Create a file, including parent directory as necessary. */
static FILE *
create_file(char *pathname, int mode)
{
FILE *f;
f = fopen(pathname, "w+");
if (f == NULL) {
/* Try creating parent dir and then creating file. */
char *p = strrchr(pathname, '/');
if (p != NULL) {
*p = '\0';
create_dir(pathname, 0755);
*p = '/';
f = fopen(pathname, "w+");
}
}
return (f);
}
/* Verify the tar checksum. */
static int
verify_checksum(const char *p)
{
int n, u = 0;
for (n = 0; n < 512; ++n) {
if (n < 148 || n > 155)
/* Standard tar checksum adds unsigned bytes. */
u += ((unsigned char *)p)[n];
else
u += 0x20;
}
return (u == parseoct(p + 148, 8));
}
/* Extract a tar archive. */
static void
untar(FILE *a, const char *path)
{
char buff[512];
FILE *f = NULL;
size_t bytes_read;
int filesize;
printf("Extracting from %s\n", path);
for (;;) {
bytes_read = fread(buff, 1, 512, a);
if (bytes_read < 512) {
fprintf(stderr,
"Short read on %s: expected 512, got %d\n",
path, (int)bytes_read);
return;
}
if (is_end_of_archive(buff)) {
printf("End of %s\n", path);
return;
}
if (!verify_checksum(buff)) {
fprintf(stderr, "Checksum failure\n");
return;
}
filesize = parseoct(buff + 124, 12);
switch (buff[156]) {
case '1':
printf(" Ignoring hardlink %s\n", buff);
break;
case '2':
printf(" Ignoring symlink %s\n", buff);
break;
case '3':
printf(" Ignoring character device %s\n", buff);
break;
case '4':
printf(" Ignoring block device %s\n", buff);
break;
case '5':
printf(" Extracting dir %s\n", buff);
create_dir(buff, parseoct(buff + 100, 8));
filesize = 0;
break;
case '6':
printf(" Ignoring FIFO %s\n", buff);
break;
default:
printf(" Extracting file %s\n", buff);
f = create_file(buff, parseoct(buff + 100, 8));
break;
}
while (filesize > 0) {
bytes_read = fread(buff, 1, 512, a);
if (bytes_read < 512) {
fprintf(stderr,
"Short read on %s: Expected 512, got %d\n",
path, (int)bytes_read);
return;
}
if (filesize < 512)
bytes_read = filesize;
if (f != NULL) {
if (fwrite(buff, 1, bytes_read, f)
!= bytes_read)
{
fprintf(stderr, "Failed write\n");
fclose(f);
f = NULL;
}
}
filesize -= bytes_read;
}
if (f != NULL) {
fclose(f);
f = NULL;
}
}
}
int
main(int argc, char **argv)
{
FILE *a;
++argv; /* Skip program name */
for ( ;*argv != NULL; ++argv) {
a = fopen(*argv, "r");
if (a == NULL)
fprintf(stderr, "Unable to open %s\n", *argv);
else {
untar(a, *argv);
fclose(a);
}
}
return (0);
}

47
cpio/CMakeLists.txt Normal file
View File

@ -0,0 +1,47 @@
############################################
#
# How to build bsdcpio
#
############################################
IF(ENABLE_CPIO)
SET(bsdcpio_SOURCES
cmdline.c
cpio.c
cpio.h
cpio_platform.h
../libarchive_fe/err.c
../libarchive_fe/err.h
../libarchive_fe/lafe_platform.h
../libarchive_fe/line_reader.c
../libarchive_fe/line_reader.h
)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libarchive_fe)
IF(WIN32 AND NOT CYGWIN)
LIST(APPEND bsdcpio_SOURCES cpio_windows.c)
LIST(APPEND bsdcpio_SOURCES cpio_windows.h)
ENDIF(WIN32 AND NOT CYGWIN)
# bsdcpio documentation
SET(bsdcpio_MANS bsdcpio.1)
# How to build bsdcpio
ADD_EXECUTABLE(bsdcpio ${bsdcpio_SOURCES})
IF(ENABLE_CPIO_SHARED)
TARGET_LINK_LIBRARIES(bsdcpio archive ${ADDITIONAL_LIBS})
ELSE(ENABLE_CPIO_SHARED)
TARGET_LINK_LIBRARIES(bsdcpio archive_static ${ADDITIONAL_LIBS})
SET_TARGET_PROPERTIES(bsdcpio PROPERTIES COMPILE_DEFINITIONS
LIBARCHIVE_STATIC)
ENDIF(ENABLE_CPIO_SHARED)
# Full path to the compiled executable (used by test suite)
GET_TARGET_PROPERTY(BSDCPIO bsdcpio LOCATION)
# Installation rules
INSTALL(TARGETS bsdcpio RUNTIME DESTINATION bin)
INSTALL_MAN(${bsdcpio_MANS})
ENDIF(ENABLE_CPIO)
# Test suite
add_subdirectory(test)

56
cpio/config_freebsd.h Normal file
View File

@ -0,0 +1,56 @@
/*-
* 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$
*/
/* A hand-tooled configuration for FreeBSD. */
#include <sys/param.h> /* __FreeBSD_version */
#define HAVE_DIRENT_H 1
#define HAVE_ERRNO_H 1
#define HAVE_FCNTL_H 1
#define HAVE_FUTIMES 1
#define HAVE_GRP_H 1
#define HAVE_LIBARCHIVE 1
#define HAVE_LINK 1
#define HAVE_LSTAT 1
#define HAVE_LUTIMES 1
#define HAVE_PWD_H 1
#define HAVE_READLINK 1
#define HAVE_STDARG_H 1
#define HAVE_STDLIB_H 1
#define HAVE_STRING_H 1
#define HAVE_SYMLINK 1
#define HAVE_SYS_CDEFS_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_SYS_TIME_H 1
#define HAVE_TIME_H 1
#define HAVE_UINTMAX_T 1
#define HAVE_UNISTD_H 1
#define HAVE_UNSIGNED_LONG_LONG 1
#define HAVE_UTIME_H 1
#define HAVE_UTIMES 1

338
cpio/cpio_windows.c Normal file
View File

@ -0,0 +1,338 @@
/*-
* Copyright (c) 2009 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$
*/
#if defined(_WIN32) && !defined(__CYGWIN__)
#include "cpio_platform.h"
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <io.h>
#include <stddef.h>
#ifdef HAVE_SYS_UTIME_H
#include <sys/utime.h>
#endif
#include <sys/stat.h>
#include <process.h>
#include <stdlib.h>
#include <wchar.h>
#include <windows.h>
#include <sddl.h>
#include "cpio.h"
#include "err.h"
#define EPOC_TIME (116444736000000000ULL)
static void cpio_dosmaperr(unsigned long);
/*
* Prepend "\\?\" to the path name and convert it to unicode to permit
* an extended-length path for a maximum total path length of 32767
* characters.
* see also http://msdn.microsoft.com/en-us/library/aa365247.aspx
*/
static wchar_t *
permissive_name(const char *name)
{
wchar_t *wn, *wnp;
wchar_t *ws, *wsp;
DWORD l, len, slen, alloclen;
int unc;
len = (DWORD)strlen(name);
wn = malloc((len + 1) * sizeof(wchar_t));
if (wn == NULL)
return (NULL);
l = MultiByteToWideChar(CP_ACP, 0, name, len, wn, len);
if (l == 0) {
free(wn);
return (NULL);
}
wn[l] = L'\0';
/* Get a full path names */
l = GetFullPathNameW(wn, 0, NULL, NULL);
if (l == 0) {
free(wn);
return (NULL);
}
wnp = malloc(l * sizeof(wchar_t));
if (wnp == NULL) {
free(wn);
return (NULL);
}
len = GetFullPathNameW(wn, l, wnp, NULL);
free(wn);
wn = wnp;
if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
wnp[2] == L'?' && wnp[3] == L'\\')
/* We have already permissive names. */
return (wn);
if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
wnp[2] == L'.' && wnp[3] == L'\\') {
/* Device names */
if (((wnp[4] >= L'a' && wnp[4] <= L'z') ||
(wnp[4] >= L'A' && wnp[4] <= L'Z')) &&
wnp[5] == L':' && wnp[6] == L'\\')
wnp[2] = L'?';/* Not device names. */
return (wn);
}
unc = 0;
if (wnp[0] == L'\\' && wnp[1] == L'\\' && wnp[2] != L'\\') {
wchar_t *p = &wnp[2];
/* Skip server-name letters. */
while (*p != L'\\' && *p != L'\0')
++p;
if (*p == L'\\') {
wchar_t *rp = ++p;
/* Skip share-name letters. */
while (*p != L'\\' && *p != L'\0')
++p;
if (*p == L'\\' && p != rp) {
/* Now, match patterns such as
* "\\server-name\share-name\" */
wnp += 2;
len -= 2;
unc = 1;
}
}
}
alloclen = slen = 4 + (unc * 4) + len + 1;
ws = wsp = malloc(slen * sizeof(wchar_t));
if (ws == NULL) {
free(wn);
return (NULL);
}
/* prepend "\\?\" */
wcsncpy(wsp, L"\\\\?\\", 4);
wsp += 4;
slen -= 4;
if (unc) {
/* append "UNC\" ---> "\\?\UNC\" */
wcsncpy(wsp, L"UNC\\", 4);
wsp += 4;
slen -= 4;
}
wcsncpy(wsp, wnp, slen);
free(wn);
ws[alloclen - 1] = L'\0';
return (ws);
}
static HANDLE
cpio_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
wchar_t *wpath;
HANDLE handle;
handle = CreateFileA(path, dwDesiredAccess, dwShareMode,
lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
hTemplateFile);
if (handle != INVALID_HANDLE_VALUE)
return (handle);
if (GetLastError() != ERROR_PATH_NOT_FOUND)
return (handle);
wpath = permissive_name(path);
if (wpath == NULL)
return (handle);
handle = CreateFileW(wpath, dwDesiredAccess, dwShareMode,
lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
hTemplateFile);
free(wpath);
return (handle);
}
#define WINTIME(sec, usec) ((Int32x32To64(sec, 10000000) + EPOC_TIME) + (usec * 10))
static int
__hutimes(HANDLE handle, const struct __timeval *times)
{
ULARGE_INTEGER wintm;
FILETIME fatime, fmtime;
wintm.QuadPart = WINTIME(times[0].tv_sec, times[0].tv_usec);
fatime.dwLowDateTime = wintm.LowPart;
fatime.dwHighDateTime = wintm.HighPart;
wintm.QuadPart = WINTIME(times[1].tv_sec, times[1].tv_usec);
fmtime.dwLowDateTime = wintm.LowPart;
fmtime.dwHighDateTime = wintm.HighPart;
if (SetFileTime(handle, NULL, &fatime, &fmtime) == 0) {
errno = EINVAL;
return (-1);
}
return (0);
}
int
futimes(int fd, const struct __timeval *times)
{
return (__hutimes((HANDLE)_get_osfhandle(fd), times));
}
int
utimes(const char *name, const struct __timeval *times)
{
int ret;
HANDLE handle;
handle = cpio_CreateFile(name, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (handle == INVALID_HANDLE_VALUE) {
cpio_dosmaperr(GetLastError());
return (-1);
}
ret = __hutimes(handle, times);
CloseHandle(handle);
return (ret);
}
/*
* The following function was modified from PostgreSQL sources and is
* subject to the copyright below.
*/
/*-------------------------------------------------------------------------
*
* win32error.c
* Map win32 error codes to errno values
*
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/port/win32error.c,v 1.4 2008/01/01 19:46:00 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
PostgreSQL Database Management System
(formerly known as Postgres, then as Postgres95)
Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
Portions Copyright (c) 1994, The Regents of the University of California
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose, without fee, and without a written agreement
is hereby granted, provided that the above copyright notice and this
paragraph and the following two paragraphs appear in all copies.
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
static const struct {
DWORD winerr;
int doserr;
} doserrors[] =
{
{ ERROR_INVALID_FUNCTION, EINVAL },
{ ERROR_FILE_NOT_FOUND, ENOENT },
{ ERROR_PATH_NOT_FOUND, ENOENT },
{ ERROR_TOO_MANY_OPEN_FILES, EMFILE },
{ ERROR_ACCESS_DENIED, EACCES },
{ ERROR_INVALID_HANDLE, EBADF },
{ ERROR_ARENA_TRASHED, ENOMEM },
{ ERROR_NOT_ENOUGH_MEMORY, ENOMEM },
{ ERROR_INVALID_BLOCK, ENOMEM },
{ ERROR_BAD_ENVIRONMENT, E2BIG },
{ ERROR_BAD_FORMAT, ENOEXEC },
{ ERROR_INVALID_ACCESS, EINVAL },
{ ERROR_INVALID_DATA, EINVAL },
{ ERROR_INVALID_DRIVE, ENOENT },
{ ERROR_CURRENT_DIRECTORY, EACCES },
{ ERROR_NOT_SAME_DEVICE, EXDEV },
{ ERROR_NO_MORE_FILES, ENOENT },
{ ERROR_LOCK_VIOLATION, EACCES },
{ ERROR_SHARING_VIOLATION, EACCES },
{ ERROR_BAD_NETPATH, ENOENT },
{ ERROR_NETWORK_ACCESS_DENIED, EACCES },
{ ERROR_BAD_NET_NAME, ENOENT },
{ ERROR_FILE_EXISTS, EEXIST },
{ ERROR_CANNOT_MAKE, EACCES },
{ ERROR_FAIL_I24, EACCES },
{ ERROR_INVALID_PARAMETER, EINVAL },
{ ERROR_NO_PROC_SLOTS, EAGAIN },
{ ERROR_DRIVE_LOCKED, EACCES },
{ ERROR_BROKEN_PIPE, EPIPE },
{ ERROR_DISK_FULL, ENOSPC },
{ ERROR_INVALID_TARGET_HANDLE, EBADF },
{ ERROR_INVALID_HANDLE, EINVAL },
{ ERROR_WAIT_NO_CHILDREN, ECHILD },
{ ERROR_CHILD_NOT_COMPLETE, ECHILD },
{ ERROR_DIRECT_ACCESS_HANDLE, EBADF },
{ ERROR_NEGATIVE_SEEK, EINVAL },
{ ERROR_SEEK_ON_DEVICE, EACCES },
{ ERROR_DIR_NOT_EMPTY, ENOTEMPTY },
{ ERROR_NOT_LOCKED, EACCES },
{ ERROR_BAD_PATHNAME, ENOENT },
{ ERROR_MAX_THRDS_REACHED, EAGAIN },
{ ERROR_LOCK_FAILED, EACCES },
{ ERROR_ALREADY_EXISTS, EEXIST },
{ ERROR_FILENAME_EXCED_RANGE, ENOENT },
{ ERROR_NESTING_NOT_ALLOWED, EAGAIN },
{ ERROR_NOT_ENOUGH_QUOTA, ENOMEM }
};
static void
cpio_dosmaperr(unsigned long e)
{
int i;
if (e == 0) {
errno = 0;
return;
}
for (i = 0; i < (int)sizeof(doserrors); i++) {
if (doserrors[i].winerr == e) {
errno = doserrors[i].doserr;
return;
}
}
/* fprintf(stderr, "unrecognized win32 error code: %lu", e); */
errno = EINVAL;
return;
}
#endif

72
cpio/cpio_windows.h Normal file
View File

@ -0,0 +1,72 @@
/*-
* Copyright (c) 2009 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 CPIO_WINDOWS_H
#define CPIO_WINDOWS_H 1
#include <io.h>
#include <string.h>
#define getgrgid(id) NULL
#define getgrnam(name) NULL
#define getpwnam(name) NULL
#define getpwuid(id) NULL
#ifdef _MSC_VER
#define snprintf sprintf_s
#define strdup _strdup
#define open _open
#define read _read
#define close _close
#endif
struct passwd {
char *pw_name;
uid_t pw_uid;
gid_t pw_gid;
};
struct group {
char *gr_name;
gid_t gr_gid;
};
struct _timeval64i32 {
time_t tv_sec;
long tv_usec;
};
#define __timeval _timeval64i32
extern int futimes(int fd, const struct __timeval *times);
#ifndef HAVE_FUTIMES
#define HAVE_FUTIMES 1
#endif
extern int utimes(const char *name, const struct __timeval *times);
#ifndef HAVE_UTIMES
#define HAVE_UTIMES 1
#endif
#endif /* CPIO_WINDOWS_H */

93
cpio/test/CMakeLists.txt Normal file
View File

@ -0,0 +1,93 @@
############################################
#
# How to build bsdcpio_test
#
############################################
IF(ENABLE_CPIO AND ENABLE_TEST)
SET(bsdcpio_test_SOURCES
../cmdline.c
../../libarchive_fe/err.c
../../test_utils/test_utils.c
main.c
test.h
test_0.c
test_basic.c
test_cmdline.c
test_extract_cpio_Z
test_extract_cpio_bz2
test_extract_cpio_grz
test_extract_cpio_gz
test_extract_cpio_lrz
test_extract_cpio_lz
test_extract_cpio_lzma
test_extract_cpio_lzo
test_extract_cpio_xz
test_format_newc.c
test_gcpio_compat.c
test_option_0.c
test_option_B_upper.c
test_option_C_upper.c
test_option_J_upper.c
test_option_L_upper.c
test_option_Z_upper.c
test_option_a.c
test_option_b64encode.c
test_option_c.c
test_option_d.c
test_option_f.c
test_option_grzip.c
test_option_help.c
test_option_l.c
test_option_lrzip.c
test_option_lzma.c
test_option_lzop.c
test_option_m.c
test_option_t.c
test_option_u.c
test_option_uuencode.c
test_option_version.c
test_option_xz.c
test_option_y.c
test_option_z.c
test_owner_parse.c
test_passthrough_dotdot.c
test_passthrough_reverse.c
)
#
# Register target
#
ADD_EXECUTABLE(bsdcpio_test ${bsdcpio_test_SOURCES})
SET_PROPERTY(TARGET bsdcpio_test PROPERTY COMPILE_DEFINITIONS LIST_H)
#
# Generate list.h by grepping DEFINE_TEST() lines out of the C sources.
#
GENERATE_LIST_H(${CMAKE_CURRENT_BINARY_DIR}/list.h
${CMAKE_CURRENT_LIST_FILE} ${bsdcpio_test_SOURCES})
SET_PROPERTY(DIRECTORY APPEND PROPERTY INCLUDE_DIRECTORIES
${CMAKE_CURRENT_BINARY_DIR})
# list.h has a line DEFINE_TEST(testname) for every
# test. We can use that to define the tests for cmake by
# defining a DEFINE_TEST macro and reading list.h in.
MACRO (DEFINE_TEST _testname)
ADD_TEST(
NAME bsdcpio_${_testname}
COMMAND bsdcpio_test -vv
-p $<TARGET_FILE:bsdcpio>
-r ${CMAKE_CURRENT_SOURCE_DIR}
${_testname})
ENDMACRO (DEFINE_TEST _testname)
INCLUDE(${CMAKE_CURRENT_BINARY_DIR}/list.h)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/test_utils)
# Experimental new test handling
ADD_CUSTOM_TARGET(run_bsdcpio_test
COMMAND bsdcpio_test -p ${BSDCPIO} -r ${CMAKE_CURRENT_SOURCE_DIR})
ADD_DEPENDENCIES(run_bsdcpio_test bsdcpio)
ADD_DEPENDENCIES(run_all_tests run_bsdcpio_test)
ENDIF(ENABLE_CPIO AND ENABLE_TEST)

2
doc/html/.ignore_me Normal file
View File

@ -0,0 +1,2 @@
*** PLEASE DO NOT DELETE THIS FILE! ***
This file is used to track an otherwise empty directory in git.

2
doc/man/.ignore_me Normal file
View File

@ -0,0 +1,2 @@
*** PLEASE DO NOT DELETE THIS FILE! ***
This file is used to track an otherwise empty directory in git.

391
doc/mdoc2man.awk Executable file
View File

@ -0,0 +1,391 @@
#!/usr/bin/awk
#
# Copyright (c) 2003 Peter Stuge <stuge-mdoc2man@cdy.org>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# Dramatically overhauled by Tim Kientzle. This version almost
# handles library-style pages with Fn, Ft, etc commands. Still
# a lot of problems...
BEGIN {
displaylines = 0
trailer = ""
out = ""
sep = ""
nextsep = " "
}
# Add a word with appropriate preceding whitespace
# Maintain a short queue of the expected upcoming word separators.
function add(str) {
out=out sep str
sep = nextsep
nextsep = " "
}
# Add a word with no following whitespace
# Use for opening punctuation such as '('
function addopen(str) {
add(str)
sep = ""
}
# Add a word with no preceding whitespace
# Use for closing punctuation such as ')' or '.'
function addclose(str) {
sep = ""
add(str)
}
# Add a word with no space before or after
# Use for separating punctuation such as '='
function addpunct(str) {
sep = ""
add(str)
sep = ""
}
# Emit the current line so far
function endline() {
addclose(trailer)
trailer = ""
if(length(out) > 0) {
print out
out=""
}
if(displaylines > 0) {
displaylines = displaylines - 1
if (displaylines == 0)
dispend()
}
# First word on next line has no preceding whitespace
sep = ""
}
function linecmd(cmd) {
endline()
add(cmd)
endline()
}
function breakline() {
linecmd(".br")
}
# Start an indented display
function dispstart() {
linecmd(".RS 4")
}
# End an indented display
function dispend() {
linecmd(".RE")
}
# Collect rest of input line
function wtail() {
retval=""
while(w<nwords) {
if(length(retval))
retval=retval " "
retval=retval words[++w]
}
return retval
}
function splitwords(l, dest, n, o, w) {
n = 1
delete dest
while (length(l) > 0) {
sub("^[ \t]*", "", l)
if (match(l, "^\"")) {
l = substr(l, 2)
o = index(l, "\"")
if (o > 0) {
w = substr(l, 1, o-1)
l = substr(l, o+1)
dest[n++] = w
} else {
dest[n++] = l
l = ""
}
} else {
o = match(l, "[ \t]")
if (o > 0) {
w = substr(l, 1, o-1)
l = substr(l, o+1)
dest[n++] = w
} else {
dest[n++] = l
l = ""
}
}
}
return n-1
}
! /^\./ {
out = $0
endline()
next
}
/^\.\\"/ { next }
{
sub("^\\.","")
nwords=splitwords($0, words)
# TODO: Instead of iterating 'w' over the array, have a separate
# function that returns 'next word' and use that. This will allow
# proper handling of double-quoted arguments as well.
for(w=1;w<=nwords;w++) {
if(match(words[w],"^Li$")) { # Literal; rest of line is unformatted
dispstart()
displaylines = 1
} else if(match(words[w],"^Dl$")) { # Display literal
dispstart()
displaylines = 1
} else if(match(words[w],"^Bd$")) { # Begin display
if(match(words[w+1],"-literal")) {
dispstart()
linecmd(".nf")
displaylines=10000
w=nwords
}
} else if(match(words[w],"^Ed$")) { # End display
displaylines = 0
dispend()
} else if(match(words[w],"^Ns$")) { # Suppress space after next word
nextsep = ""
} else if(match(words[w],"^No$")) { # Normal text
add(words[++w])
} else if(match(words[w],"^Dq$")) { # Quote
addopen("``")
add(words[++w])
while(w<nwords&&!match(words[w+1],"^[\\.,]"))
add(words[++w])
addclose("''")
} else if(match(words[w],"^Do$")) {
addopen("``")
} else if(match(words[w],"^Dc$")) {
addclose("''")
} else if(match(words[w],"^Oo$")) {
addopen("[")
} else if(match(words[w],"^Oc$")) {
addclose("]")
} else if(match(words[w],"^Ao$")) {
addopen("<")
} else if(match(words[w],"^Ac$")) {
addclose(">")
} else if(match(words[w],"^Dd$")) {
date=wtail()
next
} else if(match(words[w],"^Dt$")) {
id=wtail()
next
} else if(match(words[w],"^Ox$")) {
add("OpenBSD")
} else if(match(words[w],"^Fx$")) {
add("FreeBSD")
} else if(match(words[w],"^Nx$")) {
add("NetBSD")
} else if(match(words[w],"^St$")) {
if (match(words[w+1], "^-p1003.1$")) {
w++
add("IEEE Std 1003.1 (``POSIX.1'')")
} else if(match(words[w+1], "^-p1003.1-96$")) {
w++
add("ISO/IEC 9945-1:1996 (``POSIX.1'')")
} else if(match(words[w+1], "^-p1003.1-88$")) {
w++
add("IEEE Std 1003.1-1988 (``POSIX.1'')")
} else if(match(words[w+1], "^-p1003.1-2001$")) {
w++
add("IEEE Std 1003.1-2001 (``POSIX.1'')")
} else if(match(words[w+1], "^-susv2$")) {
w++
add("Version 2 of the Single UNIX Specification (``SUSv2'')")
}
} else if(match(words[w],"^Ex$")) {
if (match(words[w+1], "^-std$")) {
w++
add("The \\fB" name "\\fP utility exits 0 on success, and >0 if an error occurs.")
}
} else if(match(words[w],"^Os$")) {
add(".TH " id " \"" date "\" \"" wtail() "\"")
} else if(match(words[w],"^Sh$")) {
section=wtail()
add(".SH " section)
linecmd(".ad l")
} else if(match(words[w],"^Xr$")) {
add("\\fB" words[++w] "\\fP(" words[++w] ")" words[++w])
} else if(match(words[w],"^Nm$")) {
if(match(section,"SYNOPSIS"))
breakline()
if(w >= nwords)
n=name
else if (match(words[w+1], "^[A-Z][a-z]$"))
n=name
else if (match(words[w+1], "^[.,;:]$"))
n=name
else {
n=words[++w]
if(!length(name))
name=n
}
if(!length(n))
n=name
add("\\fB\\%" n "\\fP")
} else if(match(words[w],"^Nd$")) {
add("\\- " wtail())
} else if(match(words[w],"^Fl$")) {
add("\\fB\\-" words[++w] "\\fP")
} else if(match(words[w],"^Ar$")) {
addopen("\\fI")
if(w==nwords)
add("file ...\\fP")
else
add(words[++w] "\\fP")
} else if(match(words[w],"^Cm$")) {
add("\\fB" words[++w] "\\fP")
} else if(match(words[w],"^Op$")) {
addopen("[")
option=1
trailer="]" trailer
} else if(match(words[w],"^Pp$")) {
linecmd(".PP")
} else if(match(words[w],"^An$")) {
endline()
} else if(match(words[w],"^Ss$")) {
add(".SS")
} else if(match(words[w],"^Ft$")) {
if (match(section, "SYNOPSIS")) {
breakline()
}
add("\\fI" wtail() "\\fP")
if (match(section, "SYNOPSIS")) {
breakline()
}
} else if(match(words[w],"^Fn$")) {
++w
F = "\\fB\\%" words[w] "\\fP("
Fsep = ""
while(w<nwords) {
++w
if (match(words[w], "^[.,:]$")) {
--w
break
}
gsub(" ", "\\ ", words[w])
F = F Fsep "\\fI\\%" words[w] "\\fP"
Fsep = ", "
}
add(F ")")
if (match(section, "SYNOPSIS")) {
addclose(";")
}
} else if(match(words[w],"^Fo$")) {
w++
F = "\\fB\\%" words[w] "\\fP("
Fsep = ""
} else if(match(words[w],"^Fa$")) {
w++
gsub(" ", "\\ ", words[w])
F = F Fsep "\\fI\\%" words[w] "\\fP"
Fsep = ", "
} else if(match(words[w],"^Fc$")) {
add(F ")")
if (match(section, "SYNOPSIS")) {
addclose(";")
}
} else if(match(words[w],"^Va$")) {
w++
add("\\fI" words[w] "\\fP")
} else if(match(words[w],"^In$")) {
w++
add("\\fB#include <" words[w] ">\\fP")
} else if(match(words[w],"^Pa$")) {
addopen("\\fI")
w++
if(match(words[w],"^\\."))
add("\\&")
add(words[w] "\\fP")
} else if(match(words[w],"^Dv$")) {
add(".BR")
} else if(match(words[w],"^Em|Ev$")) {
add(".IR")
} else if(match(words[w],"^Pq$")) {
addopen("(")
trailer=")" trailer
} else if(match(words[w],"^Aq$")) {
addopen("\\%<")
trailer=">" trailer
} else if(match(words[w],"^Brq$")) {
addopen("{")
trailer="}" trailer
} else if(match(words[w],"^S[xy]$")) {
add(".B " wtail())
} else if(match(words[w],"^Ic$")) {
add("\\fB")
trailer="\\fP" trailer
} else if(match(words[w],"^Bl$")) {
oldoptlist=optlist
linecmd(".RS 5")
if(match(words[w+1],"-bullet"))
optlist=1
else if(match(words[w+1],"-enum")) {
optlist=2
enum=0
} else if(match(words[w+1],"-tag"))
optlist=3
else if(match(words[w+1],"-item"))
optlist=4
else if(match(words[w+1],"-bullet"))
optlist=1
w=nwords
} else if(match(words[w],"^El$")) {
linecmd(".RE")
optlist=oldoptlist
} else if(match(words[w],"^It$")&&optlist) {
if(optlist==1)
add(".IP \\(bu")
else if(optlist==2)
add(".IP " ++enum ".")
else if(optlist==3) {
add(".TP")
endline()
if(match(words[w+1],"^Pa$|^Ev$")) {
add(".B")
w++
}
} else if(optlist==4)
add(".IP")
} else if(match(words[w],"^Xo$")) {
# TODO: Figure out how to handle this
} else if(match(words[w],"^Xc$")) {
# TODO: Figure out how to handle this
} else if(match(words[w],"^[=]$")) {
addpunct(words[w])
} else if(match(words[w],"^[[{(]$")) {
addopen(words[w])
} else if(match(words[w],"^[\\])}.,;:]$")) {
addclose(words[w])
} else {
add(words[w])
}
}
if(match(out,"^\\.[^a-zA-Z]"))
sub("^\\.","",out)
endline()
}

451
doc/mdoc2wiki.awk Executable file
View File

@ -0,0 +1,451 @@
#!/usr/bin/awk
#
# Copyright (c) 2003 Peter Stuge <stuge-mdoc2man@cdy.org>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# Dramatically overhauled by Tim Kientzle. This version almost
# handles library-style pages with Fn, Ft, etc commands. Still
# a lot of problems...
BEGIN {
displaylines = 0
listdepth = 0
trailer = ""
out = ""
sep = ""
nextsep = " "
spaces = " "
NORMAL_STATE = 0
PRETAG_STATE = 1
STATE = NORMAL_STATE
}
# Add a word with appropriate preceding whitespace
# Maintain a short queue of the expected upcoming word separators.
function add(str) {
out=out sep str
sep = nextsep
nextsep = " "
}
# Add a word with no following whitespace
# Use for opening punctuation such as '('
function addopen(str) {
add(str)
sep = ""
}
# Add a word with no preceding whitespace
# Use for closing punctuation such as ')' or '.'
function addclose(str) {
sep = ""
add(str)
}
# Add a word with no space before or after
# Use for separating punctuation such as '='
function addpunct(str) {
sep = ""
add(str)
sep = ""
}
# Emit the current line so far
function endline() {
addclose(trailer)
trailer = ""
if(length(out) > 0) {
if (STATE == PRETAG_STATE) {
print out
} else {
print out " "
}
out=""
}
if(displaylines > 0) {
displaylines = displaylines - 1
if (displaylines == 0)
dispend()
}
# First word on next line has no preceding whitespace
sep = ""
}
function linecmd(cmd) {
endline()
add(cmd)
endline()
}
function breakline() {
linecmd("<br>")
}
# Start an indented display
function dispstart() {
linecmd("```text")
}
# End an indented display
function dispend() {
linecmd("```")
}
# Collect rest of input line
function wtail() {
retval=""
while(w<nwords) {
if(length(retval))
retval=retval " "
retval=retval words[++w]
}
return retval
}
function splitwords(l, dest, n, o, w) {
n = 1
delete dest
while (length(l) > 0) {
sub("^[ \t]*", "", l)
if (match(l, "^\"")) {
l = substr(l, 2)
o = index(l, "\"")
if (o > 0) {
w = substr(l, 1, o-1)
l = substr(l, o+1)
dest[n++] = w
} else {
dest[n++] = l
l = ""
}
} else {
o = match(l, "[ \t]")
if (o > 0) {
w = substr(l, 1, o-1)
l = substr(l, o+1)
dest[n++] = w
} else {
dest[n++] = l
l = ""
}
}
}
return n-1
}
! /^\./ {
out = $0
endline()
next
}
/^\.\\"/ { next }
{
sub("^\\.","")
nwords=splitwords($0, words)
# TODO: Instead of iterating 'w' over the array, have a separate
# function that returns 'next word' and use that. This will allow
# proper handling of double-quoted arguments as well.
for(w=1;w<=nwords;w++) {
if(match(words[w],"^Li$")) { # Literal; rest of line is unformatted
dispstart()
displaylines = 1
} else if(match(words[w],"^Dl$")) { # Display literal
dispstart()
displaylines = 1
} else if(match(words[w],"^Bd$")) { # Begin display
STATE = PRETAG_STATE
if(match(words[w+1],"-literal")) {
dispstart()
displaylines=10000
w=nwords
}
} else if(match(words[w],"^Ed$")) { # End display
displaylines = 0
dispend()
STATE = NORMAL_STATE
} else if(match(words[w],"^Ns$")) { # Suppress space before next word
sep=""
} else if(match(words[w],"^No$")) { # Normal text
add(words[++w])
} else if(match(words[w],"^Dq$")) { # Quote
addopen("\"")
add(words[++w])
while(w<nwords&&!match(words[w+1],"^[\\.,]"))
add(words[++w])
addclose("\"")
} else if(match(words[w],"^Do$")) {
addopen("\"")
} else if(match(words[w],"^Dc$")) {
addclose("\"")
} else if(match(words[w],"^Oo$")) {
addopen("<nowiki>[</nowiki>")
} else if(match(words[w],"^Oc$")) {
addclose("<nowiki>]</nowiki>")
} else if(match(words[w],"^Ao$")) {
addopen("&lt;")
} else if(match(words[w],"^Ac$")) {
addclose("&gt;")
} else if(match(words[w],"^Dd$")) {
date=wtail()
next
} else if(match(words[w],"^Dt$")) {
id=words[++w] "(" words[++w] ")"
next
} else if(match(words[w],"^Ox$")) {
add("OpenBSD")
} else if(match(words[w],"^Fx$")) {
add("FreeBSD")
} else if(match(words[w],"^Bx$")) {
add("BSD")
} else if(match(words[w],"^Nx$")) {
add("NetBSD")
} else if(match(words[w],"^St$")) {
if (match(words[w+1], "^-p1003.1$")) {
w++
add("<nowiki>IEEE Std 1003.1 (``POSIX.1'')</nowiki>")
} else if(match(words[w+1], "^-p1003.1-96$")) {
w++
add("<nowiki>ISO/IEC 9945-1:1996 (``POSIX.1'')</nowiki>")
} else if(match(words[w+1], "^-p1003.1-88$")) {
w++
add("<nowiki>IEEE Std 1003.1-1988 (``POSIX.1'')</nowiki>")
} else if(match(words[w+1], "^-p1003.1-2001$")) {
w++
add("<nowiki>IEEE Std 1003.1-2001 (``POSIX.1'')</nowiki>")
} else if(match(words[w+1], "^-susv2$")) {
w++
add("<nowiki>Version 2 of the Single UNIX Specification (``SUSv2'')</nowiki>")
}
} else if(match(words[w],"^Ex$")) {
if (match(words[w+1], "^-std$")) {
w++
add("The '''" name "''' utility exits 0 on success, and &gt;0 if an error occurs.")
}
} else if(match(words[w],"^Os$")) {
add(id " manual page")
} else if(match(words[w],"^Sh$")) {
section=wtail()
linecmd("== " section " ==")
} else if(match(words[w],"^Xr$")) {
add("'''" words[++w] "'''(" words[++w] ")" words[++w])
} else if(match(words[w],"^Nm$")) {
if(match(section,"SYNOPSIS"))
breakline()
if(w >= nwords)
n=name
else if (match(words[w+1], "^[A-Z][a-z]$"))
n=name
else if (match(words[w+1], "^[.,;:]$"))
n=name
else {
n=words[++w]
if(!length(name))
name=n
}
if(!length(n))
n=name
if (displaylines == 0)
add("'''" n "'''")
else
add(n)
} else if(match(words[w],"^Nd$")) {
add("- " wtail())
} else if(match(words[w],"^Fl$")) {
addopen("-")
} else if(match(words[w],"^Ar$")) {
if(w==nwords)
add("''file ...''")
else {
++w
gsub("<", "&lt;", words[w])
add("''" words[w] "''")
}
} else if(match(words[w],"^Cm$")) {
++w
if (displaylines == 0) {
add("'''" words[w] "'''")
} else
add(words[w])
} else if(match(words[w],"^Op$")) {
addopen("<nowiki>[</nowiki>")
option=1
trailer="<nowiki>]</nowiki>" trailer
} else if(match(words[w],"^Pp$")) {
++w
endline()
print ""
} else if(match(words[w],"^An$")) {
if (match(words[w+1],"-nosplit"))
++w
endline()
} else if(match(words[w],"^Ss$")) {
add("===")
trailer="==="
} else if(match(words[w],"^Ft$")) {
if (match(section, "SYNOPSIS")) {
breakline()
}
l = wtail()
add("'''" l "'''")
if (match(section, "SYNOPSIS")) {
breakline()
}
} else if(match(words[w],"^Fn$")) {
++w
F = "'''" words[w] "'''("
Fsep = ""
while(w<nwords) {
++w
if (match(words[w], "^[.,:]$")) {
--w
break
}
F = F Fsep "''" words[w] "''"
Fsep = ", "
}
add(F ")")
if (match(section, "SYNOPSIS")) {
addclose(";")
}
} else if(match(words[w],"^Fo$")) {
w++
F = "'''" words[w] "'''("
Fsep = ""
} else if(match(words[w],"^Fa$")) {
w++
F = F Fsep "''" words[w] "''"
Fsep = ", "
} else if(match(words[w],"^Fc$")) {
add(F ")")
if (match(section, "SYNOPSIS")) {
addclose(";")
}
} else if(match(words[w],"^Va$")) {
w++
add("''" words[w] "''")
} else if(match(words[w],"^In$")) {
w++
add("'''<nowiki>#include <" words[w] "></nowiki>'''")
} else if(match(words[w],"^Pa$")) {
w++
# if(match(words[w],"^\\."))
# add("\\&")
if (displaylines == 0)
add("''" words[w] "''")
else
add(words[w])
} else if(match(words[w],"^Dv$")) {
linecmd()
} else if(match(words[w],"^Em|Ev$")) {
add(".IR")
} else if(match(words[w],"^Pq$")) {
addopen("(")
trailer=")" trailer
} else if(match(words[w],"^Aq$")) {
addopen(" &lt;")
trailer="&gt;" trailer
} else if(match(words[w],"^Brq$")) {
addopen("<nowiki>{</nowiki>")
trailer="<nowiki>}</nowiki>" trailer
} else if(match(words[w],"^S[xy]$")) {
add(".B " wtail())
} else if(match(words[w],"^Tn$")) {
n=wtail()
add("'''" n "'''")
} else if(match(words[w],"^Ic$")) {
add("''")
trailer="''" trailer
} else if(match(words[w],"^Bl$")) {
++listdepth
listnext[listdepth]=""
if(match(words[w+1],"-bullet")) {
optlist[listdepth]=1
addopen("<ul>")
listclose[listdepth]="</ul>"
} else if(match(words[w+1],"-enum")) {
optlist[listdepth]=2
enum=0
addopen("<ol>")
listclose[listdepth]="</ol>"
} else if(match(words[w+1],"-tag")) {
optlist[listdepth]=3
addopen("<dl>")
listclose[listdepth]="</dl>"
} else if(match(words[w+1],"-item")) {
optlist[listdepth]=4
addopen("<ul>")
listclose[listdepth]="</ul>"
}
w=nwords
} else if(match(words[w],"^El$")) {
addclose(listnext[listdepth])
addclose(listclose[listdepth])
listclose[listdepth]=""
listdepth--
} else if(match(words[w],"^It$")) {
addclose(listnext[listdepth])
if(optlist[listdepth]==1) {
addpunct("<li>")
listnext[listdepth] = "</li>"
} else if(optlist[listdepth]==2) {
addpunct("<li>")
listnext[listdepth] = "</li>"
} else if(optlist[listdepth]==3) {
addpunct("<dt>")
listnext[listdepth] = "</dt>"
if(match(words[w+1],"^Xo$")) {
# Suppress trailer
w++
} else if(match(words[w+1],"^Pa$|^Ev$")) {
addopen("'''")
w++
add(words[++w] "'''")
} else {
trailer = listnext[listdepth] "<dd>" trailer
listnext[listdepth] = "</dd>"
}
} else if(optlist[listdepth]==4) {
addpunct("<li>")
listnext[listdepth] = "</li>"
}
} else if(match(words[w], "^Vt$")) {
w++
add("''" words[w] "''")
} else if(match(words[w],"^Xo$")) {
# TODO: Figure out how to handle this
} else if(match(words[w],"^Xc$")) {
# TODO: Figure out how to handle this
if (optlist[listdepth] == 3) {
addclose(listnext[listdepth])
addopen("<dd>")
listnext[listdepth] = "</dd>"
}
} else if(match(words[w],"^[=]$")) {
addpunct(words[w])
} else if(match(words[w],"^[[{(]$")) {
addopen(words[w])
} else if(match(words[w],"^[\\])}.,;:]$")) {
addclose(words[w])
} else {
sub("\\\\&", "", words[w])
add(words[w])
}
}
if(match(out,"^\\.[^a-zA-Z]"))
sub("^\\.","",out)
endline()
}

2
doc/pdf/.ignore_me Normal file
View File

@ -0,0 +1,2 @@
*** PLEASE DO NOT DELETE THIS FILE! ***
This file is used to track an otherwise empty directory in git.

2
doc/text/.ignore_me Normal file
View File

@ -0,0 +1,2 @@
*** PLEASE DO NOT DELETE THIS FILE! ***
This file is used to track an otherwise empty directory in git.

119
doc/update.sh Executable file
View File

@ -0,0 +1,119 @@
#!/bin/sh
set -e
#
# Simple script to repopulate the 'doc' tree from
# the mdoc man pages stored in each project.
#
# Collect list of man pages, relative to my subdirs
test -d man || mkdir man
cd man
MANPAGES=`for d in libarchive tar cpio;do ls ../../$d/*.[135];done | grep -v '\.so\.'`
cd ..
# Build Makefile in 'man' directory
cd man
chmod +w .
rm -f *.[135] Makefile
echo > Makefile
echo "default: all" >>Makefile
echo >>Makefile
all="all:"
for f in $MANPAGES; do
outname="`basename $f`"
echo >> Makefile
echo $outname: ../mdoc2man.awk $f >> Makefile
echo " awk -f ../mdoc2man.awk < $f > $outname" >> Makefile
all="$all $outname"
done
echo $all >>Makefile
cd ..
# Rebuild Makefile in 'text' directory
test -d text || mkdir text
cd text
chmod +w .
rm -f *.txt Makefile
echo > Makefile
echo "default: all" >>Makefile
echo >>Makefile
all="all:"
for f in $MANPAGES; do
outname="`basename $f`.txt"
echo >> Makefile
echo $outname: $f >> Makefile
echo " nroff -mdoc $f | col -b > $outname" >> Makefile
all="$all $outname"
done
echo $all >>Makefile
cd ..
# Rebuild Makefile in 'pdf' directory
test -d pdf || mkdir pdf
cd pdf
chmod +w .
rm -f *.pdf Makefile
echo > Makefile
echo "default: all" >>Makefile
echo >>Makefile
all="all:"
for f in $MANPAGES; do
outname="`basename $f`.pdf"
echo >> Makefile
echo $outname: $f >> Makefile
echo " groff -mdoc -T ps $f | ps2pdf - - > $outname" >> Makefile
all="$all $outname"
done
echo $all >>Makefile
cd ..
# Build Makefile in 'html' directory
test -d html || mkdir html
cd html
chmod +w .
rm -f *.html Makefile
echo > Makefile
echo "default: all" >>Makefile
echo >>Makefile
all="all:"
for f in $MANPAGES; do
outname="`basename $f`.html"
echo >> Makefile
echo $outname: $f >> Makefile
echo " groff -mdoc -T html $f > $outname" >> Makefile
all="$all $outname"
done
echo $all >>Makefile
cd ..
# Build Makefile in 'wiki' directory
test -d wiki || mkdir wiki
cd wiki
chmod +w .
rm -f *.wiki Makefile
echo > Makefile
echo "default: all" >>Makefile
echo >>Makefile
all="all:"
for f in $MANPAGES; do
outname="`basename $f | awk '{ac=split($0,a,"[_.-]");o="ManPage";for(w=0;w<=ac;++w){o=o toupper(substr(a[w],1,1)) substr(a[w],2)};print o}'`.wiki"
echo >> Makefile
echo $outname: ../mdoc2wiki.awk $f >> Makefile
echo " awk -f ../mdoc2wiki.awk < $f > $outname" >> Makefile
all="$all $outname"
done
echo $all >>Makefile
cd ..
# Convert all of the manpages to -man format
(cd man && make)
# Format all of the manpages to text
(cd text && make)
# Format all of the manpages to PDF
(cd pdf && make)
# Format all of the manpages to HTML
(cd html && make)
# Format all of the manpages to wiki syntax
(cd wiki && make)

2
doc/wiki/.ignore_me Normal file
View File

@ -0,0 +1,2 @@
*** PLEASE DO NOT DELETE THIS FILE! ***
This file is used to track an otherwise empty directory in git.

26
examples/minitar/Makefile Normal file
View File

@ -0,0 +1,26 @@
#
# Adjust the following to control which options minitar gets
# built with. See comments in minitar.c for details.
#
CFLAGS= \
-DNO_BZIP2_CREATE \
-I../../libarchive \
-g
# How to link against libarchive.
LIBARCHIVE= ../../libarchive/libarchive.a
all: minitar
minitar: minitar.o
cc -g -o minitar minitar.o $(LIBARCHIVE) -lz -lbz2
strip minitar
ls -l minitar
minitar.o: minitar.c
clean::
rm -f *.o
rm -f minitar
rm -f *~

12
examples/minitar/README Normal file
View File

@ -0,0 +1,12 @@
"minitar" is a minimal example of a program that uses libarchive to
read/write various archive formats. It's a more ambitious version of
'untar.c' that includes compile-time options to enable/disable various
features, including non-tar formats, archive creation, and automatic
decompression support.
I use this as a test bed to check for "link pollution," ensuring that
a program using libarchive does not pull in unnecessary code.
The "minitar" program is also a good starting point for anyone who
wants to use libarchive for their own purposes, as it demonstrates
basic usage of the library.

458
examples/minitar/minitar.c Normal file
View File

@ -0,0 +1,458 @@
/*-
* This file is in the public domain.
* Do with it as you will.
*/
/*-
* This is a compact "tar" program whose primary goal is small size.
* Statically linked, it can be very small indeed. This serves a number
* of goals:
* o a testbed for libarchive (to check for link pollution),
* o a useful tool for space-constrained systems (boot floppies, etc),
* o a place to experiment with new implementation ideas for bsdtar,
* o a small program to demonstrate libarchive usage.
*
* Use the following macros to suppress features:
* NO_BZIP2 - Implies NO_BZIP2_CREATE and NO_BZIP2_EXTRACT
* NO_BZIP2_CREATE - Suppress bzip2 compression support.
* NO_BZIP2_EXTRACT - Suppress bzip2 auto-detection and decompression.
* NO_COMPRESS - Implies NO_COMPRESS_CREATE and NO_COMPRESS_EXTRACT
* NO_COMPRESS_CREATE - Suppress compress(1) compression support
* NO_COMPRESS_EXTRACT - Suppress compress(1) auto-detect and decompression.
* NO_CREATE - Suppress all archive creation support.
* NO_CPIO_EXTRACT - Suppress auto-detect and dearchiving of cpio archives.
* NO_GZIP - Implies NO_GZIP_CREATE and NO_GZIP_EXTRACT
* NO_GZIP_CREATE - Suppress gzip compression support.
* NO_GZIP_EXTRACT - Suppress gzip auto-detection and decompression.
* NO_LOOKUP - Try to avoid getpw/getgr routines, which can be very large
* NO_TAR_EXTRACT - Suppress tar extraction
*
* With all of the above macros defined (except NO_TAR_EXTRACT), you
* get a very small program that can recognize and extract essentially
* any uncompressed tar archive. On FreeBSD 5.1, this minimal program
* is under 64k, statically linked, which compares rather favorably to
* main(){printf("hello, world");}
* which is over 60k statically linked on the same operating system.
* Without any of the above macros, you get a static executable of
* about 180k with a lot of very sophisticated modern features.
* Obviously, it's trivial to add support for ISO, Zip, mtree,
* lzma/xz, etc. Just fill in the appropriate setup calls.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <archive.h>
#include <archive_entry.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/*
* NO_CREATE implies NO_BZIP2_CREATE and NO_GZIP_CREATE and NO_COMPRESS_CREATE.
*/
#ifdef NO_CREATE
#undef NO_BZIP2_CREATE
#define NO_BZIP2_CREATE
#undef NO_COMPRESS_CREATE
#define NO_COMPRESS_CREATE
#undef NO_GZIP_CREATE
#define NO_GZIP_CREATE
#endif
/*
* The combination of NO_BZIP2_CREATE and NO_BZIP2_EXTRACT is
* equivalent to NO_BZIP2.
*/
#ifdef NO_BZIP2_CREATE
#ifdef NO_BZIP2_EXTRACT
#undef NO_BZIP2
#define NO_BZIP2
#endif
#endif
#ifdef NO_BZIP2
#undef NO_BZIP2_EXTRACT
#define NO_BZIP2_EXTRACT
#undef NO_BZIP2_CREATE
#define NO_BZIP2_CREATE
#endif
/*
* The combination of NO_COMPRESS_CREATE and NO_COMPRESS_EXTRACT is
* equivalent to NO_COMPRESS.
*/
#ifdef NO_COMPRESS_CREATE
#ifdef NO_COMPRESS_EXTRACT
#undef NO_COMPRESS
#define NO_COMPRESS
#endif
#endif
#ifdef NO_COMPRESS
#undef NO_COMPRESS_EXTRACT
#define NO_COMPRESS_EXTRACT
#undef NO_COMPRESS_CREATE
#define NO_COMPRESS_CREATE
#endif
/*
* The combination of NO_GZIP_CREATE and NO_GZIP_EXTRACT is
* equivalent to NO_GZIP.
*/
#ifdef NO_GZIP_CREATE
#ifdef NO_GZIP_EXTRACT
#undef NO_GZIP
#define NO_GZIP
#endif
#endif
#ifdef NO_GZIP
#undef NO_GZIP_EXTRACT
#define NO_GZIP_EXTRACT
#undef NO_GZIP_CREATE
#define NO_GZIP_CREATE
#endif
#ifndef NO_CREATE
static void create(const char *filename, int compress, const char **argv);
#endif
static void errmsg(const char *);
static void extract(const char *filename, int do_extract, int flags);
static int copy_data(struct archive *, struct archive *);
static void msg(const char *);
static void usage(void);
static int verbose = 0;
int
main(int argc, const char **argv)
{
const char *filename = NULL;
int compress, flags, mode, opt;
(void)argc;
mode = 'x';
verbose = 0;
compress = '\0';
flags = ARCHIVE_EXTRACT_TIME;
/* Among other sins, getopt(3) pulls in printf(3). */
while (*++argv != NULL && **argv == '-') {
const char *p = *argv + 1;
while ((opt = *p++) != '\0') {
switch (opt) {
#ifndef NO_CREATE
case 'c':
mode = opt;
break;
#endif
case 'f':
if (*p != '\0')
filename = p;
else
filename = *++argv;
p += strlen(p);
break;
#ifndef NO_BZIP2_CREATE
case 'j':
compress = opt;
break;
#endif
case 'p':
flags |= ARCHIVE_EXTRACT_PERM;
flags |= ARCHIVE_EXTRACT_ACL;
flags |= ARCHIVE_EXTRACT_FFLAGS;
break;
case 't':
mode = opt;
break;
case 'v':
verbose++;
break;
case 'x':
mode = opt;
break;
#ifndef NO_BZIP2_CREATE
case 'y':
compress = opt;
break;
#endif
#ifndef NO_COMPRESS_CREATE
case 'Z':
compress = opt;
break;
#endif
#ifndef NO_GZIP_CREATE
case 'z':
compress = opt;
break;
#endif
default:
usage();
}
}
}
switch (mode) {
#ifndef NO_CREATE
case 'c':
create(filename, compress, argv);
break;
#endif
case 't':
extract(filename, 0, flags);
break;
case 'x':
extract(filename, 1, flags);
break;
}
return (0);
}
#ifndef NO_CREATE
static char buff[16384];
static void
create(const char *filename, int compress, const char **argv)
{
struct archive *a;
struct archive *disk;
struct archive_entry *entry;
ssize_t len;
int fd;
a = archive_write_new();
switch (compress) {
#ifndef NO_BZIP2_CREATE
case 'j': case 'y':
archive_write_add_filter_bzip2(a);
break;
#endif
#ifndef NO_COMPRESS_CREATE
case 'Z':
archive_write_add_filter_compress(a);
break;
#endif
#ifndef NO_GZIP_CREATE
case 'z':
archive_write_add_filter_gzip(a);
break;
#endif
default:
archive_write_add_filter_none(a);
break;
}
archive_write_set_format_ustar(a);
if (strcmp(filename, "-") == 0)
filename = NULL;
archive_write_open_filename(a, filename);
disk = archive_read_disk_new();
#ifndef NO_LOOKUP
archive_read_disk_set_standard_lookup(disk);
#endif
while (*argv != NULL) {
struct archive *disk = archive_read_disk_new();
int r;
r = archive_read_disk_open(disk, *argv);
if (r != ARCHIVE_OK) {
errmsg(archive_error_string(disk));
errmsg("\n");
exit(1);
}
for (;;) {
int needcr = 0;
entry = archive_entry_new();
r = archive_read_next_header2(disk, entry);
if (r == ARCHIVE_EOF)
break;
if (r != ARCHIVE_OK) {
errmsg(archive_error_string(disk));
errmsg("\n");
exit(1);
}
archive_read_disk_descend(disk);
if (verbose) {
msg("a ");
msg(archive_entry_pathname(entry));
needcr = 1;
}
r = archive_write_header(a, entry);
if (r < ARCHIVE_OK) {
errmsg(": ");
errmsg(archive_error_string(a));
needcr = 1;
}
if (r == ARCHIVE_FATAL)
exit(1);
if (r > ARCHIVE_FAILED) {
#if 0
/* Ideally, we would be able to use
* the same code to copy a body from
* an archive_read_disk to an
* archive_write that we use for
* copying data from an archive_read
* to an archive_write_disk.
* Unfortunately, this doesn't quite
* work yet. */
copy_data(disk, a);
#else
/* For now, we use a simpler loop to copy data
* into the target archive. */
fd = open(archive_entry_sourcepath(entry), O_RDONLY);
len = read(fd, buff, sizeof(buff));
while (len > 0) {
archive_write_data(a, buff, len);
len = read(fd, buff, sizeof(buff));
}
close(fd);
#endif
}
archive_entry_free(entry);
if (needcr)
msg("\n");
}
archive_read_close(disk);
archive_read_free(disk);
argv++;
}
archive_write_close(a);
archive_write_free(a);
}
#endif
static void
extract(const char *filename, int do_extract, int flags)
{
struct archive *a;
struct archive *ext;
struct archive_entry *entry;
int r;
a = archive_read_new();
ext = archive_write_disk_new();
archive_write_disk_set_options(ext, flags);
#ifndef NO_BZIP2_EXTRACT
archive_read_support_filter_bzip2(a);
#endif
#ifndef NO_GZIP_EXTRACT
archive_read_support_filter_gzip(a);
#endif
#ifndef NO_COMPRESS_EXTRACT
archive_read_support_filter_compress(a);
#endif
#ifndef NO_TAR_EXTRACT
archive_read_support_format_tar(a);
#endif
#ifndef NO_CPIO_EXTRACT
archive_read_support_format_cpio(a);
#endif
#ifndef NO_LOOKUP
archive_write_disk_set_standard_lookup(ext);
#endif
if (filename != NULL && strcmp(filename, "-") == 0)
filename = NULL;
if ((r = archive_read_open_filename(a, filename, 10240))) {
errmsg(archive_error_string(a));
errmsg("\n");
exit(r);
}
for (;;) {
r = archive_read_next_header(a, &entry);
if (r == ARCHIVE_EOF)
break;
if (r != ARCHIVE_OK) {
errmsg(archive_error_string(a));
errmsg("\n");
exit(1);
}
if (verbose && do_extract)
msg("x ");
if (verbose || !do_extract)
msg(archive_entry_pathname(entry));
if (do_extract) {
r = archive_write_header(ext, entry);
if (r != ARCHIVE_OK)
errmsg(archive_error_string(a));
else
copy_data(a, ext);
}
if (verbose || !do_extract)
msg("\n");
}
archive_read_close(a);
archive_read_free(a);
exit(0);
}
static int
copy_data(struct archive *ar, struct archive *aw)
{
int r;
const void *buff;
size_t size;
off_t offset;
for (;;) {
r = archive_read_data_block(ar, &buff, &size, &offset);
if (r == ARCHIVE_EOF) {
errmsg(archive_error_string(ar));
return (ARCHIVE_OK);
}
if (r != ARCHIVE_OK)
return (r);
r = archive_write_data_block(aw, buff, size, offset);
if (r != ARCHIVE_OK) {
errmsg(archive_error_string(ar));
return (r);
}
}
}
static void
msg(const char *m)
{
write(1, m, strlen(m));
}
static void
errmsg(const char *m)
{
write(2, m, strlen(m));
}
static void
usage(void)
{
/* Many program options depend on compile options. */
const char *m = "Usage: minitar [-"
#ifndef NO_CREATE
"c"
#endif
#ifndef NO_BZIP2
"j"
#endif
"tvx"
#ifndef NO_BZIP2
"y"
#endif
#ifndef NO_COMPRESS
"Z"
#endif
#ifndef NO_GZIP
"z"
#endif
"] [-f file] [file]\n";
errmsg(m);
exit(1);
}

113
examples/tarfilter.c Normal file
View File

@ -0,0 +1,113 @@
/*
* This file is in the public domain.
*
* Feel free to use it as you wish.
*/
/*
* This example program reads an archive from stdin (which can be in
* any format recognized by libarchive) and writes certain entries to
* an uncompressed ustar archive on stdout. This is a template for
* many kinds of archive manipulation: converting formats, resetting
* ownership, inserting entries, removing entries, etc.
*
* To compile:
* gcc -Wall -o tarfilter tarfilter.c -larchive -lz -lbz2
*/
#include <sys/stat.h>
#include <archive.h>
#include <archive_entry.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
static void
die(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, "\n");
exit(1);
}
int
main(int argc, char **argv)
{
char buff[8192];
ssize_t len;
int r;
mode_t m;
struct archive *ina;
struct archive *outa;
struct archive_entry *entry;
/* Read an archive from stdin, with automatic format detection. */
ina = archive_read_new();
if (ina == NULL)
die("Couldn't create archive reader.");
if (archive_read_support_filter_all(ina) != ARCHIVE_OK)
die("Couldn't enable decompression");
if (archive_read_support_format_all(ina) != ARCHIVE_OK)
die("Couldn't enable read formats");
if (archive_read_open_fd(ina, 0, 10240) != ARCHIVE_OK)
die("Couldn't open input archive");
/* Write an uncompressed ustar archive to stdout. */
outa = archive_write_new();
if (outa == NULL)
die("Couldn't create archive writer.");
if (archive_write_set_compression_none(outa) != ARCHIVE_OK)
die("Couldn't enable compression");
if (archive_write_set_format_ustar(outa) != ARCHIVE_OK)
die("Couldn't set output format");
if (archive_write_open_fd(outa, 1) != ARCHIVE_OK)
die("Couldn't open output archive");
/* Examine each entry in the input archive. */
while ((r = archive_read_next_header(ina, &entry)) == ARCHIVE_OK) {
fprintf(stderr, "%s: ", archive_entry_pathname(entry));
/* Skip anything that isn't a regular file. */
if (!S_ISREG(archive_entry_mode(entry))) {
fprintf(stderr, "skipped\n");
continue;
}
/* Make everything owned by root/wheel. */
archive_entry_set_uid(entry, 0);
archive_entry_set_uname(entry, "root");
archive_entry_set_gid(entry, 0);
archive_entry_set_gname(entry, "wheel");
/* Make everything permission 0744, strip SUID, etc. */
m = archive_entry_mode(entry);
archive_entry_set_mode(entry, (m & ~07777) | 0744);
/* Copy input entries to output archive. */
if (archive_write_header(outa, entry) != ARCHIVE_OK)
die("Error writing output archive");
if (archive_entry_size(entry) > 0) {
len = archive_read_data(ina, buff, sizeof(buff));
while (len > 0) {
if (archive_write_data(outa, buff, len) != len)
die("Error writing output archive");
len = archive_read_data(ina, buff, sizeof(buff));
}
if (len < 0)
die("Error reading input archive");
}
fprintf(stderr, "copied\n");
}
if (r != ARCHIVE_EOF)
die("Error reading archive");
/* Close the archives. */
if (archive_read_free(ina) != ARCHIVE_OK)
die("Error closing input archive");
if (archive_write_free(outa) != ARCHIVE_OK)
die("Error closing output archive");
return (0);
}

266
examples/untar.c Normal file
View File

@ -0,0 +1,266 @@
/*
* This file is in the public domain.
* Use it as you wish.
*/
/*
* This is a compact tar extraction program using libarchive whose
* primary goal is small executable size. Statically linked, it can
* be very small, depending in large part on how cleanly factored your
* system libraries are. Note that this uses the standard libarchive,
* without any special recompilation. The only functional concession
* is that this program uses the uid/gid from the archive instead of
* doing uname/gname lookups. (Add a call to
* archive_write_disk_set_standard_lookup() to enable uname/gname
* lookups, but be aware that this can add 500k or more to a static
* executable, depending on the system libraries, since user/group
* lookups frequently pull in password, YP/LDAP, networking, and DNS
* resolver libraries.)
*
* To build:
* $ gcc -static -Wall -o untar untar.c -larchive
* $ strip untar
*
* NOTE: On some systems, you may need to add additional flags
* to ensure that untar.c is compiled the same way as libarchive
* was compiled. In particular, Linux users will probably
* have to add -D_FILE_OFFSET_BITS=64 to the command line above.
*
* For fun, statically compile the following simple hello.c program
* using the same flags as for untar and compare the size:
*
* #include <stdio.h>
* int main(int argc, char **argv) {
* printf("hello, world\n");
* return(0);
* }
*
* You may be even more surprised by the compiled size of true.c listed here:
*
* int main(int argc, char **argv) {
* return (0);
* }
*
* On a slightly customized FreeBSD 5 system that I used around
* 2005, hello above compiled to 89k compared to untar of 69k. So at
* that time, libarchive's tar reader and extract-to-disk routines
* compiled to less code than printf().
*
* On my FreeBSD development system today (August, 2009):
* hello: 195024 bytes
* true: 194912 bytes
* untar: 259924 bytes
*/
#include <sys/types.h>
__FBSDID("$FreeBSD$");
#include <sys/stat.h>
#include <archive.h>
#include <archive_entry.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static void errmsg(const char *);
static void extract(const char *filename, int do_extract, int flags);
static void fail(const char *, const char *, int);
static int copy_data(struct archive *, struct archive *);
static void msg(const char *);
static void usage(void);
static void warn(const char *, const char *);
static int verbose = 0;
int
main(int argc, const char **argv)
{
const char *filename = NULL;
int compress, flags, mode, opt;
(void)argc;
mode = 'x';
verbose = 0;
compress = '\0';
flags = ARCHIVE_EXTRACT_TIME;
/* Among other sins, getopt(3) pulls in printf(3). */
while (*++argv != NULL && **argv == '-') {
const char *p = *argv + 1;
while ((opt = *p++) != '\0') {
switch (opt) {
case 'f':
if (*p != '\0')
filename = p;
else
filename = *++argv;
p += strlen(p);
break;
case 'p':
flags |= ARCHIVE_EXTRACT_PERM;
flags |= ARCHIVE_EXTRACT_ACL;
flags |= ARCHIVE_EXTRACT_FFLAGS;
break;
case 't':
mode = opt;
break;
case 'v':
verbose++;
break;
case 'x':
mode = opt;
break;
default:
usage();
}
}
}
switch (mode) {
case 't':
extract(filename, 0, flags);
break;
case 'x':
extract(filename, 1, flags);
break;
}
return (0);
}
static void
extract(const char *filename, int do_extract, int flags)
{
struct archive *a;
struct archive *ext;
struct archive_entry *entry;
int r;
a = archive_read_new();
ext = archive_write_disk_new();
archive_write_disk_set_options(ext, flags);
/*
* Note: archive_write_disk_set_standard_lookup() is useful
* here, but it requires library routines that can add 500k or
* more to a static executable.
*/
archive_read_support_format_tar(a);
/*
* On my system, enabling other archive formats adds 20k-30k
* each. Enabling gzip decompression adds about 20k.
* Enabling bzip2 is more expensive because the libbz2 library
* isn't very well factored.
*/
if (filename != NULL && strcmp(filename, "-") == 0)
filename = NULL;
if ((r = archive_read_open_filename(a, filename, 10240)))
fail("archive_read_open_filename()",
archive_error_string(a), r);
for (;;) {
r = archive_read_next_header(a, &entry);
if (r == ARCHIVE_EOF)
break;
if (r != ARCHIVE_OK)
fail("archive_read_next_header()",
archive_error_string(a), 1);
if (verbose && do_extract)
msg("x ");
if (verbose || !do_extract)
msg(archive_entry_pathname(entry));
if (do_extract) {
r = archive_write_header(ext, entry);
if (r != ARCHIVE_OK)
warn("archive_write_header()",
archive_error_string(ext));
else {
copy_data(a, ext);
r = archive_write_finish_entry(ext);
if (r != ARCHIVE_OK)
fail("archive_write_finish_entry()",
archive_error_string(ext), 1);
}
}
if (verbose || !do_extract)
msg("\n");
}
archive_read_close(a);
archive_read_free(a);
exit(0);
}
static int
copy_data(struct archive *ar, struct archive *aw)
{
int r;
const void *buff;
size_t size;
#if ARCHIVE_VERSION >= 3000000
int64_t offset;
#else
off_t offset;
#endif
for (;;) {
r = archive_read_data_block(ar, &buff, &size, &offset);
if (r == ARCHIVE_EOF)
return (ARCHIVE_OK);
if (r != ARCHIVE_OK)
return (r);
r = archive_write_data_block(aw, buff, size, offset);
if (r != ARCHIVE_OK) {
warn("archive_write_data_block()",
archive_error_string(aw));
return (r);
}
}
}
/*
* These reporting functions use low-level I/O; on some systems, this
* is a significant code reduction. Of course, on many server and
* desktop operating systems, malloc() and even crt rely on printf(),
* which in turn pulls in most of the rest of stdio, so this is not an
* optimization at all there. (If you're going to pay 100k or more
* for printf() anyway, you may as well use it!)
*/
static void
msg(const char *m)
{
write(1, m, strlen(m));
}
static void
errmsg(const char *m)
{
write(2, m, strlen(m));
}
static void
warn(const char *f, const char *m)
{
errmsg(f);
errmsg(" failed: ");
errmsg(m);
errmsg("\n");
}
static void
fail(const char *f, const char *m, int r)
{
warn(f, m);
exit(r);
}
static void
usage(void)
{
const char *m = "Usage: untar [-tvx] [-f file] [file]\n";
errmsg(m);
exit(1);
}

193
libarchive/CMakeLists.txt Normal file
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)

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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,908 @@
/*-
* Copyright (c) 2009-2011 Michihiro NAKAJIMA
* Copyright (c) 2003-2007 Kees Zeelenberg
* 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$
*/
/*
* A set of compatibility glue for building libarchive on Windows platforms.
*
* Originally created as "libarchive-nonposix.c" by Kees Zeelenberg
* for the GnuWin32 project, trimmed significantly by Tim Kientzle.
*
* Much of the original file was unnecessary for libarchive, because
* many of the features it emulated were not strictly necessary for
* libarchive. I hope for this to shrink further as libarchive
* internals are gradually reworked to sit more naturally on both
* POSIX and Windows. Any ideas for this are greatly appreciated.
*
* The biggest remaining issue is the dev/ino emulation; libarchive
* has a couple of public APIs that rely on dev/ino uniquely
* identifying a file. This doesn't match well with Windows. I'm
* considering alternative APIs.
*/
#if defined(_WIN32) && !defined(__CYGWIN__)
#include "archive_platform.h"
#include "archive_private.h"
#include "archive_entry.h"
#include <ctype.h>
#include <errno.h>
#include <stddef.h>
#ifdef HAVE_SYS_UTIME_H
#include <sys/utime.h>
#endif
#include <sys/stat.h>
#include <locale.h>
#include <process.h>
#include <stdlib.h>
#include <wchar.h>
#include <windows.h>
#include <share.h>
#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
#if defined(__LA_LSEEK_NEEDED)
static BOOL SetFilePointerEx_perso(HANDLE hFile,
LARGE_INTEGER liDistanceToMove,
PLARGE_INTEGER lpNewFilePointer,
DWORD dwMoveMethod)
{
LARGE_INTEGER li;
li.QuadPart = liDistanceToMove.QuadPart;
li.LowPart = SetFilePointer(
hFile, li.LowPart, &li.HighPart, dwMoveMethod);
if(lpNewFilePointer) {
lpNewFilePointer->QuadPart = li.QuadPart;
}
return li.LowPart != -1 || GetLastError() == NO_ERROR;
}
#endif
struct ustat {
int64_t st_atime;
uint32_t st_atime_nsec;
int64_t st_ctime;
uint32_t st_ctime_nsec;
int64_t st_mtime;
uint32_t st_mtime_nsec;
gid_t st_gid;
/* 64bits ino */
int64_t st_ino;
mode_t st_mode;
uint32_t st_nlink;
uint64_t st_size;
uid_t st_uid;
dev_t st_dev;
dev_t st_rdev;
};
/* Transform 64-bits ino into 32-bits by hashing.
* You do not forget that really unique number size is 64-bits.
*/
#define INOSIZE (8*sizeof(ino_t)) /* 32 */
static __inline ino_t
getino(struct ustat *ub)
{
ULARGE_INTEGER ino64;
ino64.QuadPart = ub->st_ino;
/* I don't know this hashing is correct way */
return ((ino_t)(ino64.LowPart ^ (ino64.LowPart >> INOSIZE)));
}
/*
* Prepend "\\?\" to the path name and convert it to unicode to permit
* an extended-length path for a maximum total path length of 32767
* characters.
* see also http://msdn.microsoft.com/en-us/library/aa365247.aspx
*/
wchar_t *
__la_win_permissive_name(const char *name)
{
wchar_t *wn;
wchar_t *ws;
size_t ll;
ll = strlen(name);
wn = malloc((ll + 1) * sizeof(wchar_t));
if (wn == NULL)
return (NULL);
ll = mbstowcs(wn, name, ll);
if (ll == (size_t)-1) {
free(wn);
return (NULL);
}
wn[ll] = L'\0';
ws = __la_win_permissive_name_w(wn);
free(wn);
return (ws);
}
wchar_t *
__la_win_permissive_name_w(const wchar_t *wname)
{
wchar_t *wn, *wnp;
wchar_t *ws, *wsp;
DWORD l, len, slen;
int unc;
/* Get a full-pathname. */
l = GetFullPathNameW(wname, 0, NULL, NULL);
if (l == 0)
return (NULL);
/* NOTE: GetFullPathNameW has a bug that if the length of the file
* name is just 1 then it returns incomplete buffer size. Thus, we
* have to add three to the size to allocate a sufficient buffer
* size for the full-pathname of the file name. */
l += 3;
wnp = malloc(l * sizeof(wchar_t));
if (wnp == NULL)
return (NULL);
len = GetFullPathNameW(wname, l, wnp, NULL);
wn = wnp;
if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
wnp[2] == L'?' && wnp[3] == L'\\')
/* We have already a permissive name. */
return (wn);
if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
wnp[2] == L'.' && wnp[3] == L'\\') {
/* This is a device name */
if (((wnp[4] >= L'a' && wnp[4] <= L'z') ||
(wnp[4] >= L'A' && wnp[4] <= L'Z')) &&
wnp[5] == L':' && wnp[6] == L'\\')
wnp[2] = L'?';/* Not device name. */
return (wn);
}
unc = 0;
if (wnp[0] == L'\\' && wnp[1] == L'\\' && wnp[2] != L'\\') {
wchar_t *p = &wnp[2];
/* Skip server-name letters. */
while (*p != L'\\' && *p != L'\0')
++p;
if (*p == L'\\') {
wchar_t *rp = ++p;
/* Skip share-name letters. */
while (*p != L'\\' && *p != L'\0')
++p;
if (*p == L'\\' && p != rp) {
/* Now, match patterns such as
* "\\server-name\share-name\" */
wnp += 2;
len -= 2;
unc = 1;
}
}
}
slen = 4 + (unc * 4) + len + 1;
ws = wsp = malloc(slen * sizeof(wchar_t));
if (ws == NULL) {
free(wn);
return (NULL);
}
/* prepend "\\?\" */
wcsncpy(wsp, L"\\\\?\\", 4);
wsp += 4;
slen -= 4;
if (unc) {
/* append "UNC\" ---> "\\?\UNC\" */
wcsncpy(wsp, L"UNC\\", 4);
wsp += 4;
slen -= 4;
}
wcsncpy(wsp, wnp, slen);
wsp[slen - 1] = L'\0'; /* Ensure null termination. */
free(wn);
return (ws);
}
/*
* Create a file handle.
* This can exceed MAX_PATH limitation.
*/
static HANDLE
la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
wchar_t *wpath;
HANDLE handle;
handle = CreateFileA(path, dwDesiredAccess, dwShareMode,
lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
hTemplateFile);
if (handle != INVALID_HANDLE_VALUE)
return (handle);
if (GetLastError() != ERROR_PATH_NOT_FOUND)
return (handle);
wpath = __la_win_permissive_name(path);
if (wpath == NULL)
return (handle);
handle = CreateFileW(wpath, dwDesiredAccess, dwShareMode,
lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
hTemplateFile);
free(wpath);
return (handle);
}
#if defined(__LA_LSEEK_NEEDED)
__int64
__la_lseek(int fd, __int64 offset, int whence)
{
LARGE_INTEGER distance;
LARGE_INTEGER newpointer;
HANDLE handle;
if (fd < 0) {
errno = EBADF;
return (-1);
}
handle = (HANDLE)_get_osfhandle(fd);
if (GetFileType(handle) != FILE_TYPE_DISK) {
errno = EBADF;
return (-1);
}
distance.QuadPart = offset;
if (!SetFilePointerEx_perso(handle, distance, &newpointer, whence)) {
DWORD lasterr;
lasterr = GetLastError();
if (lasterr == ERROR_BROKEN_PIPE)
return (0);
if (lasterr == ERROR_ACCESS_DENIED)
errno = EBADF;
else
la_dosmaperr(lasterr);
return (-1);
}
return (newpointer.QuadPart);
}
#endif
/* This can exceed MAX_PATH limitation. */
int
__la_open(const char *path, int flags, ...)
{
va_list ap;
wchar_t *ws;
int r, pmode;
DWORD attr;
va_start(ap, flags);
pmode = va_arg(ap, int);
va_end(ap);
ws = NULL;
if ((flags & ~O_BINARY) == O_RDONLY) {
/*
* When we open a directory, _open function returns
* "Permission denied" error.
*/
attr = GetFileAttributesA(path);
if (attr == (DWORD)-1 && GetLastError() == ERROR_PATH_NOT_FOUND) {
ws = __la_win_permissive_name(path);
if (ws == NULL) {
errno = EINVAL;
return (-1);
}
attr = GetFileAttributesW(ws);
}
if (attr == (DWORD)-1) {
la_dosmaperr(GetLastError());
free(ws);
return (-1);
}
if (attr & FILE_ATTRIBUTE_DIRECTORY) {
HANDLE handle;
if (ws != NULL)
handle = CreateFileW(ws, 0, 0, NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS |
FILE_ATTRIBUTE_READONLY,
NULL);
else
handle = CreateFileA(path, 0, 0, NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS |
FILE_ATTRIBUTE_READONLY,
NULL);
free(ws);
if (handle == INVALID_HANDLE_VALUE) {
la_dosmaperr(GetLastError());
return (-1);
}
r = _open_osfhandle((intptr_t)handle, _O_RDONLY);
return (r);
}
}
if (ws == NULL) {
#if defined(__BORLANDC__)
/* Borland has no mode argument.
TODO: Fix mode of new file. */
r = _open(path, flags);
#else
r = _open(path, flags, pmode);
#endif
if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
/* Simulate other POSIX system action to pass our test suite. */
attr = GetFileAttributesA(path);
if (attr == (DWORD)-1)
la_dosmaperr(GetLastError());
else if (attr & FILE_ATTRIBUTE_DIRECTORY)
errno = EISDIR;
else
errno = EACCES;
return (-1);
}
if (r >= 0 || errno != ENOENT)
return (r);
ws = __la_win_permissive_name(path);
if (ws == NULL) {
errno = EINVAL;
return (-1);
}
}
r = _wopen(ws, flags, pmode);
if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
/* Simulate other POSIX system action to pass our test suite. */
attr = GetFileAttributesW(ws);
if (attr == (DWORD)-1)
la_dosmaperr(GetLastError());
else if (attr & FILE_ATTRIBUTE_DIRECTORY)
errno = EISDIR;
else
errno = EACCES;
}
free(ws);
return (r);
}
ssize_t
__la_read(int fd, void *buf, size_t nbytes)
{
HANDLE handle;
DWORD bytes_read, lasterr;
int r;
#ifdef _WIN64
if (nbytes > UINT32_MAX)
nbytes = UINT32_MAX;
#endif
if (fd < 0) {
errno = EBADF;
return (-1);
}
/* Do not pass 0 to third parameter of ReadFile(), read bytes.
* This will not return to application side. */
if (nbytes == 0)
return (0);
handle = (HANDLE)_get_osfhandle(fd);
r = ReadFile(handle, buf, (uint32_t)nbytes,
&bytes_read, NULL);
if (r == 0) {
lasterr = GetLastError();
if (lasterr == ERROR_NO_DATA) {
errno = EAGAIN;
return (-1);
}
if (lasterr == ERROR_BROKEN_PIPE)
return (0);
if (lasterr == ERROR_ACCESS_DENIED)
errno = EBADF;
else
la_dosmaperr(lasterr);
return (-1);
}
return ((ssize_t)bytes_read);
}
/* Convert Windows FILETIME to UTC */
__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;
}
}
/* Stat by handle
* Windows' stat() does not accept the path added "\\?\" especially "?"
* character.
* It means we cannot access the long name path longer than MAX_PATH.
* So I've implemented simular Windows' stat() to access the long name path.
* And I've added some feature.
* 1. set st_ino by nFileIndexHigh and nFileIndexLow of
* BY_HANDLE_FILE_INFORMATION.
* 2. set st_nlink by nNumberOfLinks of BY_HANDLE_FILE_INFORMATION.
* 3. set st_dev by dwVolumeSerialNumber by BY_HANDLE_FILE_INFORMATION.
*/
static int
__hstat(HANDLE handle, struct ustat *st)
{
BY_HANDLE_FILE_INFORMATION info;
ULARGE_INTEGER ino64;
DWORD ftype;
mode_t mode;
time_t t;
long ns;
switch (ftype = GetFileType(handle)) {
case FILE_TYPE_UNKNOWN:
errno = EBADF;
return (-1);
case FILE_TYPE_CHAR:
case FILE_TYPE_PIPE:
if (ftype == FILE_TYPE_CHAR) {
st->st_mode = S_IFCHR;
st->st_size = 0;
} else {
DWORD avail;
st->st_mode = S_IFIFO;
if (PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL))
st->st_size = avail;
else
st->st_size = 0;
}
st->st_atime = 0;
st->st_atime_nsec = 0;
st->st_mtime = 0;
st->st_mtime_nsec = 0;
st->st_ctime = 0;
st->st_ctime_nsec = 0;
st->st_ino = 0;
st->st_nlink = 1;
st->st_uid = 0;
st->st_gid = 0;
st->st_rdev = 0;
st->st_dev = 0;
return (0);
case FILE_TYPE_DISK:
break;
default:
/* This ftype is undocumented type. */
la_dosmaperr(GetLastError());
return (-1);
}
ZeroMemory(&info, sizeof(info));
if (!GetFileInformationByHandle (handle, &info)) {
la_dosmaperr(GetLastError());
return (-1);
}
mode = S_IRUSR | S_IRGRP | S_IROTH;
if ((info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
mode |= S_IWUSR | S_IWGRP | S_IWOTH;
if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
else
mode |= S_IFREG;
st->st_mode = mode;
fileTimeToUTC(&info.ftLastAccessTime, &t, &ns);
st->st_atime = t;
st->st_atime_nsec = ns;
fileTimeToUTC(&info.ftLastWriteTime, &t, &ns);
st->st_mtime = t;
st->st_mtime_nsec = ns;
fileTimeToUTC(&info.ftCreationTime, &t, &ns);
st->st_ctime = t;
st->st_ctime_nsec = ns;
st->st_size =
((int64_t)(info.nFileSizeHigh) * ((int64_t)MAXDWORD + 1))
+ (int64_t)(info.nFileSizeLow);
#ifdef SIMULATE_WIN_STAT
st->st_ino = 0;
st->st_nlink = 1;
st->st_dev = 0;
#else
/* Getting FileIndex as i-node. We should remove a sequence which
* is high-16-bits of nFileIndexHigh. */
ino64.HighPart = info.nFileIndexHigh & 0x0000FFFFUL;
ino64.LowPart = info.nFileIndexLow;
st->st_ino = ino64.QuadPart;
st->st_nlink = info.nNumberOfLinks;
if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
++st->st_nlink;/* Add parent directory. */
st->st_dev = info.dwVolumeSerialNumber;
#endif
st->st_uid = 0;
st->st_gid = 0;
st->st_rdev = 0;
return (0);
}
static void
copy_stat(struct stat *st, struct ustat *us)
{
st->st_atime = us->st_atime;
st->st_ctime = us->st_ctime;
st->st_mtime = us->st_mtime;
st->st_gid = us->st_gid;
st->st_ino = getino(us);
st->st_mode = us->st_mode;
st->st_nlink = us->st_nlink;
st->st_size = (off_t)us->st_size;
st->st_uid = us->st_uid;
st->st_dev = us->st_dev;
st->st_rdev = us->st_rdev;
}
/*
* TODO: Remove a use of __la_fstat and __la_stat.
* We should use GetFileInformationByHandle in place
* where We still use the *stat functions.
*/
int
__la_fstat(int fd, struct stat *st)
{
struct ustat u;
int ret;
if (fd < 0) {
errno = EBADF;
return (-1);
}
ret = __hstat((HANDLE)_get_osfhandle(fd), &u);
if (ret >= 0) {
copy_stat(st, &u);
if (u.st_mode & (S_IFCHR | S_IFIFO)) {
st->st_dev = fd;
st->st_rdev = fd;
}
}
return (ret);
}
/* This can exceed MAX_PATH limitation. */
int
__la_stat(const char *path, struct stat *st)
{
HANDLE handle;
struct ustat u;
int ret;
handle = la_CreateFile(path, 0, 0, NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL);
if (handle == INVALID_HANDLE_VALUE) {
la_dosmaperr(GetLastError());
return (-1);
}
ret = __hstat(handle, &u);
CloseHandle(handle);
if (ret >= 0) {
char *p;
copy_stat(st, &u);
p = strrchr(path, '.');
if (p != NULL && strlen(p) == 4) {
char exttype[4];
++ p;
exttype[0] = toupper(*p++);
exttype[1] = toupper(*p++);
exttype[2] = toupper(*p++);
exttype[3] = '\0';
if (!strcmp(exttype, "EXE") || !strcmp(exttype, "CMD") ||
!strcmp(exttype, "BAT") || !strcmp(exttype, "COM"))
st->st_mode |= S_IXUSR | S_IXGRP | S_IXOTH;
}
}
return (ret);
}
/*
* This waitpid is limited implementation.
*/
pid_t
__la_waitpid(HANDLE child, int *status, int option)
{
DWORD cs;
(void)option;/* UNUSED */
do {
if (GetExitCodeProcess(child, &cs) == 0) {
CloseHandle(child);
la_dosmaperr(GetLastError());
*status = 0;
return (-1);
}
} while (cs == STILL_ACTIVE);
*status = (int)(cs & 0xff);
return (0);
}
ssize_t
__la_write(int fd, const void *buf, size_t nbytes)
{
DWORD bytes_written;
#ifdef _WIN64
if (nbytes > UINT32_MAX)
nbytes = UINT32_MAX;
#endif
if (fd < 0) {
errno = EBADF;
return (-1);
}
if (!WriteFile((HANDLE)_get_osfhandle(fd), buf, (uint32_t)nbytes,
&bytes_written, NULL)) {
DWORD lasterr;
lasterr = GetLastError();
if (lasterr == ERROR_ACCESS_DENIED)
errno = EBADF;
else
la_dosmaperr(lasterr);
return (-1);
}
return (bytes_written);
}
/*
* Replace the Windows path separator '\' with '/'.
*/
static int
replace_pathseparator(struct archive_wstring *ws, const wchar_t *wp)
{
wchar_t *w;
size_t path_length;
if (wp == NULL)
return(0);
if (wcschr(wp, L'\\') == NULL)
return(0);
path_length = wcslen(wp);
if (archive_wstring_ensure(ws, path_length) == NULL)
return(-1);
archive_wstrncpy(ws, wp, path_length);
for (w = ws->s; *w; w++) {
if (*w == L'\\')
*w = L'/';
}
return(1);
}
static int
fix_pathseparator(struct archive_entry *entry)
{
struct archive_wstring ws;
const wchar_t *wp;
int ret = ARCHIVE_OK;
archive_string_init(&ws);
wp = archive_entry_pathname_w(entry);
switch (replace_pathseparator(&ws, wp)) {
case 0: /* Not replaced. */
break;
case 1: /* Replaced. */
archive_entry_copy_pathname_w(entry, ws.s);
break;
default:
ret = ARCHIVE_FAILED;
}
wp = archive_entry_hardlink_w(entry);
switch (replace_pathseparator(&ws, wp)) {
case 0: /* Not replaced. */
break;
case 1: /* Replaced. */
archive_entry_copy_hardlink_w(entry, ws.s);
break;
default:
ret = ARCHIVE_FAILED;
}
wp = archive_entry_symlink_w(entry);
switch (replace_pathseparator(&ws, wp)) {
case 0: /* Not replaced. */
break;
case 1: /* Replaced. */
archive_entry_copy_symlink_w(entry, ws.s);
break;
default:
ret = ARCHIVE_FAILED;
}
archive_wstring_free(&ws);
return(ret);
}
struct archive_entry *
__la_win_entry_in_posix_pathseparator(struct archive_entry *entry)
{
struct archive_entry *entry_main;
const wchar_t *wp;
int has_backslash = 0;
int ret;
wp = archive_entry_pathname_w(entry);
if (wp != NULL && wcschr(wp, L'\\') != NULL)
has_backslash = 1;
if (!has_backslash) {
wp = archive_entry_hardlink_w(entry);
if (wp != NULL && wcschr(wp, L'\\') != NULL)
has_backslash = 1;
}
if (!has_backslash) {
wp = archive_entry_symlink_w(entry);
if (wp != NULL && wcschr(wp, L'\\') != NULL)
has_backslash = 1;
}
/*
* If there is no backslach chars, return the original.
*/
if (!has_backslash)
return (entry);
/* Copy entry so we can modify it as needed. */
entry_main = archive_entry_clone(entry);
if (entry_main == NULL)
return (NULL);
/* Replace the Windows path-separator '\' with '/'. */
ret = fix_pathseparator(entry_main);
if (ret < ARCHIVE_WARN) {
archive_entry_free(entry_main);
return (NULL);
}
return (entry_main);
}
/*
* The following function was modified from PostgreSQL sources and is
* subject to the copyright below.
*/
/*-------------------------------------------------------------------------
*
* win32error.c
* Map win32 error codes to errno values
*
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/port/win32error.c,v 1.4 2008/01/01 19:46:00 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
PostgreSQL Database Management System
(formerly known as Postgres, then as Postgres95)
Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
Portions Copyright (c) 1994, The Regents of the University of California
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose, without fee, and without a written agreement
is hereby granted, provided that the above copyright notice and this
paragraph and the following two paragraphs appear in all copies.
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
static const struct {
DWORD winerr;
int doserr;
} doserrors[] =
{
{ ERROR_INVALID_FUNCTION, EINVAL },
{ ERROR_FILE_NOT_FOUND, ENOENT },
{ ERROR_PATH_NOT_FOUND, ENOENT },
{ ERROR_TOO_MANY_OPEN_FILES, EMFILE },
{ ERROR_ACCESS_DENIED, EACCES },
{ ERROR_INVALID_HANDLE, EBADF },
{ ERROR_ARENA_TRASHED, ENOMEM },
{ ERROR_NOT_ENOUGH_MEMORY, ENOMEM },
{ ERROR_INVALID_BLOCK, ENOMEM },
{ ERROR_BAD_ENVIRONMENT, E2BIG },
{ ERROR_BAD_FORMAT, ENOEXEC },
{ ERROR_INVALID_ACCESS, EINVAL },
{ ERROR_INVALID_DATA, EINVAL },
{ ERROR_INVALID_DRIVE, ENOENT },
{ ERROR_CURRENT_DIRECTORY, EACCES },
{ ERROR_NOT_SAME_DEVICE, EXDEV },
{ ERROR_NO_MORE_FILES, ENOENT },
{ ERROR_LOCK_VIOLATION, EACCES },
{ ERROR_SHARING_VIOLATION, EACCES },
{ ERROR_BAD_NETPATH, ENOENT },
{ ERROR_NETWORK_ACCESS_DENIED, EACCES },
{ ERROR_BAD_NET_NAME, ENOENT },
{ ERROR_FILE_EXISTS, EEXIST },
{ ERROR_CANNOT_MAKE, EACCES },
{ ERROR_FAIL_I24, EACCES },
{ ERROR_INVALID_PARAMETER, EINVAL },
{ ERROR_NO_PROC_SLOTS, EAGAIN },
{ ERROR_DRIVE_LOCKED, EACCES },
{ ERROR_BROKEN_PIPE, EPIPE },
{ ERROR_DISK_FULL, ENOSPC },
{ ERROR_INVALID_TARGET_HANDLE, EBADF },
{ ERROR_INVALID_HANDLE, EINVAL },
{ ERROR_WAIT_NO_CHILDREN, ECHILD },
{ ERROR_CHILD_NOT_COMPLETE, ECHILD },
{ ERROR_DIRECT_ACCESS_HANDLE, EBADF },
{ ERROR_NEGATIVE_SEEK, EINVAL },
{ ERROR_SEEK_ON_DEVICE, EACCES },
{ ERROR_DIR_NOT_EMPTY, ENOTEMPTY },
{ ERROR_NOT_LOCKED, EACCES },
{ ERROR_BAD_PATHNAME, ENOENT },
{ ERROR_MAX_THRDS_REACHED, EAGAIN },
{ ERROR_LOCK_FAILED, EACCES },
{ ERROR_ALREADY_EXISTS, EEXIST },
{ ERROR_FILENAME_EXCED_RANGE, ENOENT },
{ ERROR_NESTING_NOT_ALLOWED, EAGAIN },
{ ERROR_NOT_ENOUGH_QUOTA, ENOMEM }
};
void
__la_dosmaperr(unsigned long e)
{
int i;
if (e == 0)
{
errno = 0;
return;
}
for (i = 0; i < (int)sizeof(doserrors); i++)
{
if (doserrors[i].winerr == e)
{
errno = doserrors[i].doserr;
return;
}
}
/* fprintf(stderr, "unrecognized win32 error code: %lu", e); */
errno = EINVAL;
return;
}
#endif /* _WIN32 && !__CYGWIN__ */

View File

@ -0,0 +1,306 @@
/*-
* Copyright (c) 2009-2011 Michihiro NAKAJIMA
* Copyright (c) 2003-2006 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
#error This header is only to be used internally to libarchive.
#endif
/*
* TODO: A lot of stuff in here isn't actually used by libarchive and
* can be trimmed out. Note that this file is used by libarchive and
* libarchive_test but nowhere else. (But note that it gets compiled
* with many different Windows environments, including MinGW, Visual
* Studio, and Cygwin. Significant changes should be tested in all three.)
*/
/*
* TODO: Don't use off_t in here. Use __int64 instead. Note that
* Visual Studio and the Windows SDK define off_t as 32 bits; Win32's
* more modern file handling APIs all use __int64 instead of off_t.
*/
#ifndef LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED
#define LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED
/* Start of configuration for native Win32 */
#ifndef MINGW_HAS_SECURE_API
#define MINGW_HAS_SECURE_API 1
#endif
#include <errno.h>
#define set_errno(val) ((errno)=val)
#include <io.h>
#include <stdlib.h> //brings in NULL
#if defined(HAVE_STDINT_H)
#include <stdint.h>
#endif
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <process.h>
#include <direct.h>
#if defined(__MINGW32__) && defined(HAVE_UNISTD_H)
/* Prevent build error from a type mismatch of ftruncate().
* This unistd.h defines it as ftruncate(int, off_t). */
#include <unistd.h>
#endif
#define NOCRYPT
#include <windows.h>
//#define EFTYPE 7
#if defined(__BORLANDC__)
#pragma warn -8068 /* Constant out of range in comparison. */
#pragma warn -8072 /* Suspicious pointer arithmetic. */
#endif
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
/* Alias the Windows _function to the POSIX equivalent. */
#define close _close
#define fcntl(fd, cmd, flg) /* No operation. */
#ifndef fileno
#define fileno _fileno
#endif
#ifdef fstat
#undef fstat
#endif
#define fstat __la_fstat
#if !defined(__BORLANDC__)
#ifdef lseek
#undef lseek
#endif
#define lseek _lseeki64
#else
#define lseek __la_lseek
#define __LA_LSEEK_NEEDED
#endif
#define lstat __la_stat
#define open __la_open
#define read __la_read
#if !defined(__BORLANDC__)
#define setmode _setmode
#endif
#ifdef stat
#undef stat
#endif
#define stat(path,stref) __la_stat(path,stref)
#if !defined(__BORLANDC__)
#define strdup _strdup
#endif
#define tzset _tzset
#if !defined(__BORLANDC__)
#define umask _umask
#endif
#define waitpid __la_waitpid
#define write __la_write
#ifndef O_RDONLY
#define O_RDONLY _O_RDONLY
#define O_WRONLY _O_WRONLY
#define O_TRUNC _O_TRUNC
#define O_CREAT _O_CREAT
#define O_EXCL _O_EXCL
#define O_BINARY _O_BINARY
#endif
#ifndef _S_IFIFO
#define _S_IFIFO 0010000 /* pipe */
#endif
#ifndef _S_IFCHR
#define _S_IFCHR 0020000 /* character special */
#endif
#ifndef _S_IFDIR
#define _S_IFDIR 0040000 /* directory */
#endif
#ifndef _S_IFBLK
#define _S_IFBLK 0060000 /* block special */
#endif
#ifndef _S_IFLNK
#define _S_IFLNK 0120000 /* symbolic link */
#endif
#ifndef _S_IFSOCK
#define _S_IFSOCK 0140000 /* socket */
#endif
#ifndef _S_IFREG
#define _S_IFREG 0100000 /* regular */
#endif
#ifndef _S_IFMT
#define _S_IFMT 0170000 /* file type mask */
#endif
#ifndef S_IFIFO
#define S_IFIFO _S_IFIFO
#endif
//#define S_IFCHR _S_IFCHR
//#define S_IFDIR _S_IFDIR
#ifndef S_IFBLK
#define S_IFBLK _S_IFBLK
#endif
#ifndef S_IFLNK
#define S_IFLNK _S_IFLNK
#endif
#ifndef S_IFSOCK
#define S_IFSOCK _S_IFSOCK
#endif
//#define S_IFREG _S_IFREG
//#define S_IFMT _S_IFMT
#ifndef S_ISBLK
#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) /* block special */
#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) /* fifo or socket */
#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) /* char special */
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) /* directory */
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) /* regular file */
#endif
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) /* Symbolic link */
#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) /* Socket */
#define _S_ISUID 0004000 /* set user id on execution */
#define _S_ISGID 0002000 /* set group id on execution */
#define _S_ISVTX 0001000 /* save swapped text even after use */
#define S_ISUID _S_ISUID
#define S_ISGID _S_ISGID
#define S_ISVTX _S_ISVTX
#define _S_IRWXU (_S_IREAD | _S_IWRITE | _S_IEXEC)
#define _S_IXUSR _S_IEXEC /* read permission, user */
#define _S_IWUSR _S_IWRITE /* write permission, user */
#define _S_IRUSR _S_IREAD /* execute/search permission, user */
#define _S_IRWXG (_S_IRWXU >> 3)
#define _S_IXGRP (_S_IXUSR >> 3) /* read permission, group */
#define _S_IWGRP (_S_IWUSR >> 3) /* write permission, group */
#define _S_IRGRP (_S_IRUSR >> 3) /* execute/search permission, group */
#define _S_IRWXO (_S_IRWXG >> 3)
#define _S_IXOTH (_S_IXGRP >> 3) /* read permission, other */
#define _S_IWOTH (_S_IWGRP >> 3) /* write permission, other */
#define _S_IROTH (_S_IRGRP >> 3) /* execute/search permission, other */
#ifndef S_IRWXU
#define S_IRWXU _S_IRWXU
#define S_IXUSR _S_IXUSR
#define S_IWUSR _S_IWUSR
#define S_IRUSR _S_IRUSR
#endif
#define S_IRWXG _S_IRWXG
#define S_IXGRP _S_IXGRP
#define S_IWGRP _S_IWGRP
#define S_IRGRP _S_IRGRP
#define S_IRWXO _S_IRWXO
#define S_IXOTH _S_IXOTH
#define S_IWOTH _S_IWOTH
#define S_IROTH _S_IROTH
#define F_DUPFD 0 /* Duplicate file descriptor. */
#define F_GETFD 1 /* Get file descriptor flags. */
#define F_SETFD 2 /* Set file descriptor flags. */
#define F_GETFL 3 /* Get file status flags. */
#define F_SETFL 4 /* Set file status flags. */
#define F_GETOWN 5 /* Get owner (receiver of SIGIO). */
#define F_SETOWN 6 /* Set owner (receiver of SIGIO). */
#define F_GETLK 7 /* Get record locking info. */
#define F_SETLK 8 /* Set record locking info (non-blocking). */
#define F_SETLKW 9 /* Set record locking info (blocking). */
/* XXX missing */
#define F_GETLK64 7 /* Get record locking info. */
#define F_SETLK64 8 /* Set record locking info (non-blocking). */
#define F_SETLKW64 9 /* Set record locking info (blocking). */
/* File descriptor flags used with F_GETFD and F_SETFD. */
#define FD_CLOEXEC 1 /* Close on exec. */
//NOT SURE IF O_NONBLOCK is OK here but at least the 0x0004 flag is not used by anything else...
#define O_NONBLOCK 0x0004 /* Non-blocking I/O. */
//#define O_NDELAY O_NONBLOCK
/* Symbolic constants for the access() function */
#if !defined(F_OK)
#define R_OK 4 /* Test for read permission */
#define W_OK 2 /* Test for write permission */
#define X_OK 1 /* Test for execute permission */
#define F_OK 0 /* Test for existence of file */
#endif
/* Replacement POSIX function */
extern int __la_fstat(int fd, struct stat *st);
extern int __la_lstat(const char *path, struct stat *st);
#if defined(__LA_LSEEK_NEEDED)
extern __int64 __la_lseek(int fd, __int64 offset, int whence);
#endif
extern int __la_open(const char *path, int flags, ...);
extern ssize_t __la_read(int fd, void *buf, size_t nbytes);
extern int __la_stat(const char *path, struct stat *st);
extern pid_t __la_waitpid(HANDLE child, int *status, int option);
extern ssize_t __la_write(int fd, const void *buf, size_t nbytes);
#define _stat64i32(path, st) __la_stat(path, st)
#define _stat64(path, st) __la_stat(path, st)
/* for status returned by la_waitpid */
#define WIFEXITED(sts) ((sts & 0x100) == 0)
#define WEXITSTATUS(sts) (sts & 0x0FF)
extern wchar_t *__la_win_permissive_name(const char *name);
extern wchar_t *__la_win_permissive_name_w(const wchar_t *wname);
extern void __la_dosmaperr(unsigned long e);
#define la_dosmaperr(e) __la_dosmaperr(e)
extern struct archive_entry *__la_win_entry_in_posix_pathseparator(
struct archive_entry *);
#if defined(HAVE_WCRTOMB) && defined(__BORLANDC__)
typedef int mbstate_t;
size_t wcrtomb(char *, wchar_t, mbstate_t *);
#endif
#if defined(_MSC_VER) && _MSC_VER < 1300
WINBASEAPI BOOL WINAPI GetVolumePathNameW(
LPCWSTR lpszFileName,
LPWSTR lpszVolumePathName,
DWORD cchBufferLength
);
# if _WIN32_WINNT < 0x0500 /* windows.h not providing 0x500 API */
typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
LARGE_INTEGER FileOffset;
LARGE_INTEGER Length;
} FILE_ALLOCATED_RANGE_BUFFER, *PFILE_ALLOCATED_RANGE_BUFFER;
# define FSCTL_SET_SPARSE \
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 49, METHOD_BUFFERED, FILE_WRITE_DATA)
# define FSCTL_QUERY_ALLOCATED_RANGES \
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 51, METHOD_NEITHER, FILE_READ_DATA)
# endif
#endif
#endif /* LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED */

File diff suppressed because it is too large Load Diff

160
libarchive/config_freebsd.h Normal file
View File

@ -0,0 +1,160 @@
/*-
* 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$
*/
/* FreeBSD 5.0 and later have ACL and extattr support. */
#if __FreeBSD__ > 4
#define HAVE_ACL_CREATE_ENTRY 1
#define HAVE_ACL_GET_LINK_NP 1
#define HAVE_ACL_GET_PERM_NP 1
#define HAVE_ACL_INIT 1
#define HAVE_ACL_SET_FD 1
#define HAVE_ACL_SET_FD_NP 1
#define HAVE_ACL_SET_FILE 1
#define HAVE_ACL_USER 1
#define HAVE_EXTATTR_GET_FILE 1
#define HAVE_EXTATTR_LIST_FILE 1
#define HAVE_EXTATTR_SET_FD 1
#define HAVE_EXTATTR_SET_FILE 1
#define HAVE_SYS_ACL_H 1
#define HAVE_SYS_EXTATTR_H 1
#endif
#ifdef WITH_OPENSSL
#define HAVE_OPENSSL_MD5_H 1
#define HAVE_OPENSSL_RIPEMD_H 1
#define HAVE_OPENSSL_SHA_H 1
#define HAVE_SHA384 1
#define HAVE_SHA512 1
#endif
#define HAVE_BSDXML_H 1
#define HAVE_BZLIB_H 1
#define HAVE_CHFLAGS 1
#define HAVE_CHOWN 1
#define HAVE_DECL_INT64_MAX 1
#define HAVE_DECL_INT64_MIN 1
#define HAVE_DECL_SIZE_MAX 1
#define HAVE_DECL_SSIZE_MAX 1
#define HAVE_DECL_STRERROR_R 1
#define HAVE_DECL_UINT32_MAX 1
#define HAVE_DECL_UINT64_MAX 1
#define HAVE_DIRENT_H 1
#define HAVE_EFTYPE 1
#define HAVE_EILSEQ 1
#define HAVE_ERRNO_H 1
#define HAVE_FCHDIR 1
#define HAVE_FCHFLAGS 1
#define HAVE_FCHMOD 1
#define HAVE_FCHOWN 1
#define HAVE_FCNTL 1
#define HAVE_FCNTL_H 1
#define HAVE_FSEEKO 1
#define HAVE_FSTAT 1
#define HAVE_FTRUNCATE 1
#define HAVE_FUTIMES 1
#define HAVE_GETEUID 1
#define HAVE_GETGRGID_R 1
#define HAVE_GETPID 1
#define HAVE_GETPWUID_R 1
#define HAVE_GRP_H 1
#define HAVE_INTTYPES_H 1
#define HAVE_LCHFLAGS 1
#define HAVE_LCHMOD 1
#define HAVE_LCHOWN 1
#define HAVE_LIMITS_H 1
#define HAVE_LINK 1
#define HAVE_LSTAT 1
#define HAVE_LUTIMES 1
#define HAVE_MALLOC 1
#define HAVE_MD5 1
#define HAVE_MD5_H 1
#define HAVE_MEMMOVE 1
#define HAVE_MKDIR 1
#define HAVE_MKFIFO 1
#define HAVE_MKNOD 1
#define HAVE_PIPE 1
#define HAVE_POLL 1
#define HAVE_POLL_H 1
#define HAVE_PWD_H 1
#define HAVE_READLINK 1
#define HAVE_RMD160 1
#define HAVE_SELECT 1
#define HAVE_SETENV 1
#define HAVE_SHA_H 1
#define HAVE_SHA1 1
#define HAVE_SHA256 1
#define HAVE_SHA256_H 1
#define HAVE_SIGNAL_H 1
#define HAVE_STDINT_H 1
#define HAVE_STDLIB_H 1
#define HAVE_STRCHR 1
#define HAVE_STRDUP 1
#define HAVE_STRERROR 1
#define HAVE_STRERROR_R 1
#define HAVE_STRINGS_H 1
#define HAVE_STRING_H 1
#define HAVE_STRRCHR 1
#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1
#define HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC 1
#define HAVE_STRUCT_STAT_ST_FLAGS 1
#define HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1
#define HAVE_STRUCT_TM_TM_GMTOFF 1
#define HAVE_SYMLINK 1
#define HAVE_SYS_CDEFS_H 1
#define HAVE_SYS_IOCTL_H 1
#define HAVE_SYS_MOUNT_H 1
#define HAVE_SYS_PARAM_H 1
#define HAVE_SYS_SELECT_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_SYS_TIME_H 1
#define HAVE_SYS_TYPES_H 1
#undef HAVE_SYS_UTIME_H
#define HAVE_SYS_UTSNAME_H 1
#define HAVE_SYS_WAIT_H 1
#define HAVE_TIMEGM 1
#define HAVE_TZSET 1
#define HAVE_UNISTD_H 1
#define HAVE_UNSETENV 1
#define HAVE_UTIME 1
#define HAVE_UTIMES 1
#define HAVE_UTIME_H 1
#define HAVE_VFORK 1
#define HAVE_WCHAR_H 1
#define HAVE_WCSCPY 1
#define HAVE_WCSLEN 1
#define HAVE_WCTOMB 1
#define HAVE_WMEMCMP 1
#define HAVE_WMEMCPY 1
#define HAVE_ZLIB_H 1
#define TIME_WITH_SYS_TIME 1
/* FreeBSD 4 and earlier lack intmax_t/uintmax_t */
#if __FreeBSD__ < 5
#define intmax_t int64_t
#define uintmax_t uint64_t
#endif

View File

@ -0,0 +1,190 @@
/*-
* Copyright (c) 2009-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"
#if defined(_WIN32) && !defined(__CYGWIN__)
#include "archive_cmdline_private.h"
#include "archive_string.h"
#include "filter_fork.h"
pid_t
__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout)
{
HANDLE childStdout[2], childStdin[2],childStderr;
SECURITY_ATTRIBUTES secAtts;
STARTUPINFO staInfo;
PROCESS_INFORMATION childInfo;
struct archive_string cmdline;
struct archive_string fullpath;
struct archive_cmdline *acmd;
char *arg0, *ext;
int i, l;
DWORD fl, fl_old;
childStdout[0] = childStdout[1] = INVALID_HANDLE_VALUE;
childStdin[0] = childStdin[1] = INVALID_HANDLE_VALUE;
childStderr = INVALID_HANDLE_VALUE;
archive_string_init(&cmdline);
archive_string_init(&fullpath);
acmd = __archive_cmdline_allocate();
if (acmd == NULL)
goto fail;
if (__archive_cmdline_parse(acmd, cmd) != ARCHIVE_OK)
goto fail;
/*
* Search the full path of 'path'.
* NOTE: This does not need if we give CreateProcessA 'path' as
* a part of the cmdline and give CreateProcessA NULL as first
* parameter, but I do not like that way.
*/
ext = strrchr(acmd->path, '.');
if (ext == NULL || strlen(ext) > 4)
/* 'path' does not have a proper extension, so we have to
* give SearchPath() ".exe" as the extension. */
ext = ".exe";
else
ext = NULL;/* 'path' has an extension. */
fl = MAX_PATH;
do {
if (archive_string_ensure(&fullpath, fl) == NULL)
goto fail;
fl_old = fl;
fl = SearchPathA(NULL, acmd->path, ext, fl, fullpath.s,
&arg0);
} while (fl != 0 && fl > fl_old);
if (fl == 0)
goto fail;
/*
* Make a command line.
*/
for (l = 0, i = 0; acmd->argv[i] != NULL; i++) {
if (i == 0)
continue;
l += (int)strlen(acmd->argv[i]) + 1;
}
if (archive_string_ensure(&cmdline, l + 1) == NULL)
goto fail;
for (i = 0; acmd->argv[i] != NULL; i++) {
if (i == 0) {
const char *p, *sp;
if ((p = strchr(acmd->argv[i], '/')) != NULL ||
(p = strchr(acmd->argv[i], '\\')) != NULL)
p++;
else
p = acmd->argv[i];
if ((sp = strchr(p, ' ')) != NULL)
archive_strappend_char(&cmdline, '"');
archive_strcat(&cmdline, p);
if (sp != NULL)
archive_strappend_char(&cmdline, '"');
} else {
archive_strappend_char(&cmdline, ' ');
archive_strcat(&cmdline, acmd->argv[i]);
}
}
if (i <= 1) {
const char *sp;
if ((sp = strchr(arg0, ' ')) != NULL)
archive_strappend_char(&cmdline, '"');
archive_strcat(&cmdline, arg0);
if (sp != NULL)
archive_strappend_char(&cmdline, '"');
}
secAtts.nLength = sizeof(SECURITY_ATTRIBUTES);
secAtts.bInheritHandle = TRUE;
secAtts.lpSecurityDescriptor = NULL;
if (CreatePipe(&childStdout[0], &childStdout[1], &secAtts, 0) == 0)
goto fail;
if (!SetHandleInformation(childStdout[0], HANDLE_FLAG_INHERIT, 0))
goto fail;
if (CreatePipe(&childStdin[0], &childStdin[1], &secAtts, 0) == 0)
goto fail;
if (!SetHandleInformation(childStdin[1], HANDLE_FLAG_INHERIT, 0))
goto fail;
if (DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_ERROR_HANDLE),
GetCurrentProcess(), &childStderr, 0, TRUE,
DUPLICATE_SAME_ACCESS) == 0)
goto fail;
memset(&staInfo, 0, sizeof(staInfo));
staInfo.cb = sizeof(staInfo);
staInfo.hStdError = childStderr;
staInfo.hStdOutput = childStdout[1];
staInfo.hStdInput = childStdin[0];
staInfo.wShowWindow = SW_HIDE;
staInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
if (CreateProcessA(fullpath.s, cmdline.s, NULL, NULL, TRUE, 0,
NULL, NULL, &staInfo, &childInfo) == 0)
goto fail;
WaitForInputIdle(childInfo.hProcess, INFINITE);
CloseHandle(childInfo.hProcess);
CloseHandle(childInfo.hThread);
*child_stdout = _open_osfhandle((intptr_t)childStdout[0], _O_RDONLY);
*child_stdin = _open_osfhandle((intptr_t)childStdin[1], _O_WRONLY);
CloseHandle(childStdout[1]);
CloseHandle(childStdin[0]);
archive_string_free(&cmdline);
archive_string_free(&fullpath);
__archive_cmdline_free(acmd);
return (childInfo.dwProcessId);
fail:
if (childStdout[0] != INVALID_HANDLE_VALUE)
CloseHandle(childStdout[0]);
if (childStdout[1] != INVALID_HANDLE_VALUE)
CloseHandle(childStdout[1]);
if (childStdin[0] != INVALID_HANDLE_VALUE)
CloseHandle(childStdin[0]);
if (childStdin[1] != INVALID_HANDLE_VALUE)
CloseHandle(childStdin[1]);
if (childStderr != INVALID_HANDLE_VALUE)
CloseHandle(childStderr);
archive_string_free(&cmdline);
archive_string_free(&fullpath);
__archive_cmdline_free(acmd);
return (-1);
}
void
__archive_check_child(int in, int out)
{
(void)in; /* UNUSED */
(void)out; /* UNUSED */
Sleep(100);
}
#endif /* _WIN32 && !__CYGWIN__ */

269
libarchive/mtree.5 Normal file
View File

@ -0,0 +1,269 @@
.\" Copyright (c) 1989, 1990, 1993
.\" The Regents of the University of California. 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.
.\" 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.
.\"
.\" From: @(#)mtree.8 8.2 (Berkeley) 12/11/93
.\" $FreeBSD$
.\"
.Dd May 6, 2008
.Dt MTREE 5
.Os
.Sh NAME
.Nm mtree
.Nd format of mtree dir hierarchy files
.Sh DESCRIPTION
The
.Nm
format is a textual format that describes a collection of filesystem objects.
Such files are typically used to create or verify directory hierarchies.
.Ss General Format
An
.Nm
file consists of a series of lines, each providing information
about a single filesystem object.
Leading whitespace is always ignored.
.Pp
When encoding file or pathnames, any backslash character or
character outside of the 95 printable ASCII characters must be
encoded as a a backslash followed by three
octal digits.
When reading mtree files, any appearance of a backslash
followed by three octal digits should be converted into the
corresponding character.
.Pp
Each line is interpreted independently as one of the following types:
.Bl -tag -width Cm
.It Signature
The first line of any mtree file must begin with
.Dq #mtree .
If a file contains any full path entries, the first line should
begin with
.Dq #mtree v2.0 ,
otherwise, the first line should begin with
.Dq #mtree v1.0 .
.It Blank
Blank lines are ignored.
.It Comment
Lines beginning with
.Cm #
are ignored.
.It Special
Lines beginning with
.Cm /
are special commands that influence
the interpretation of later lines.
.It Relative
If the first whitespace-delimited word has no
.Cm /
characters,
it is the name of a file in the current directory.
Any relative entry that describes a directory changes the
current directory.
.It dot-dot
As a special case, a relative entry with the filename
.Pa ..
changes the current directory to the parent directory.
Options on dot-dot entries are always ignored.
.It Full
If the first whitespace-delimited word has a
.Cm /
character after
the first character, it is the pathname of a file relative to the
starting directory.
There can be multiple full entries describing the same file.
.El
.Pp
Some tools that process
.Nm
files may require that multiple lines describing the same file
occur consecutively.
It is not permitted for the same file to be mentioned using
both a relative and a full file specification.
.Ss Special commands
Two special commands are currently defined:
.Bl -tag -width Cm
.It Cm /set
This command defines default values for one or more keywords.
It is followed on the same line by one or more whitespace-separated
keyword definitions.
These definitions apply to all following files that do not specify
a value for that keyword.
.It Cm /unset
This command removes any default value set by a previous
.Cm /set
command.
It is followed on the same line by one or more keywords
separated by whitespace.
.El
.Ss Keywords
After the filename, a full or relative entry consists of zero
or more whitespace-separated keyword definitions.
Each such definition consists of a key from the following
list immediately followed by an '=' sign
and a value.
Software programs reading mtree files should warn about
unrecognized keywords.
.Pp
Currently supported keywords are as follows:
.Bl -tag -width Cm
.It Cm cksum
The checksum of the file using the default algorithm specified by
the
.Xr cksum 1
utility.
.It Cm contents
The full pathname of a file that holds the contents of this file.
.It Cm flags
The file flags as a symbolic name.
See
.Xr chflags 1
for information on these names.
If no flags are to be set the string
.Dq none
may be used to override the current default.
.It Cm gid
The file group as a numeric value.
.It Cm gname
The file group as a symbolic name.
.It Cm ignore
Ignore any file hierarchy below this file.
.It Cm link
The target of the symbolic link when type=link.
.It Cm md5
The MD5 message digest of the file.
.It Cm md5digest
A synonym for
.Cm md5 .
.It Cm mode
The current file's permissions as a numeric (octal) or symbolic
value.
.It Cm nlink
The number of hard links the file is expected to have.
.It Cm nochange
Make sure this file or directory exists but otherwise ignore all attributes.
.It Cm ripemd160digest
The
.Tn RIPEMD160
message digest of the file.
.It Cm rmd160
A synonym for
.Cm ripemd160digest .
.It Cm rmd160digest
A synonym for
.Cm ripemd160digest .
.It Cm sha1
The
.Tn FIPS
160-1
.Pq Dq Tn SHA-1
message digest of the file.
.It Cm sha1digest
A synonym for
.Cm sha1 .
.It Cm sha256
The
.Tn FIPS
180-2
.Pq Dq Tn SHA-256
message digest of the file.
.It Cm sha256digest
A synonym for
.Cm sha256 .
.It Cm size
The size, in bytes, of the file.
.It Cm time
The last modification time of the file.
.It Cm type
The type of the file; may be set to any one of the following:
.Pp
.Bl -tag -width Cm -compact
.It Cm block
block special device
.It Cm char
character special device
.It Cm dir
directory
.It Cm fifo
fifo
.It Cm file
regular file
.It Cm link
symbolic link
.It Cm socket
socket
.El
.It Cm uid
The file owner as a numeric value.
.It Cm uname
The file owner as a symbolic name.
.El
.Pp
.Sh SEE ALSO
.Xr cksum 1 ,
.Xr find 1 ,
.Xr mtree 8
.Sh BUGS
The
.Fx
implementation of mtree does not currently support
the
.Nm
2.0
format.
The requirement for a
.Dq #mtree
signature line is new and not yet widely implemented.
.Sh HISTORY
The
.Nm
utility appeared in
.Bx 4.3 Reno .
The
.Tn MD5
digest capability was added in
.Fx 2.1 ,
in response to the widespread use of programs which can spoof
.Xr cksum 1 .
The
.Tn SHA-1
and
.Tn RIPEMD160
digests were added in
.Fx 4.0 ,
as new attacks have demonstrated weaknesses in
.Tn MD5 .
The
.Tn SHA-256
digest was added in
.Fx 6.0 .
Support for file flags was added in
.Fx 4.0 ,
and mostly comes from
.Nx .
The
.Dq full
entry format was added by
.Nx .

View File

@ -0,0 +1,10 @@
*.tar
*.tar.gz
*.tgz
*.zip
.depend
.deps
.dirstamp
archive.h
libarchive_test
list.h

View File

@ -0,0 +1,256 @@
############################################
#
# How to build libarchive_test
#
############################################
IF(ENABLE_TEST)
SET(libarchive_test_SOURCES
../../test_utils/test_utils.c
main.c
read_open_memory.c
test.h
test_acl_freebsd_posix1e.c
test_acl_freebsd_nfs4.c
test_acl_nfs4.c
test_acl_pax.c
test_acl_posix1e.c
test_archive_api_feature.c
test_archive_clear_error.c
test_archive_cmdline.c
test_archive_crypto.c
test_archive_getdate.c
test_archive_match_owner.c
test_archive_match_path.c
test_archive_match_time.c
test_archive_pathmatch.c
test_archive_read_close_twice.c
test_archive_read_close_twice_open_fd.c
test_archive_read_close_twice_open_filename.c
test_archive_read_multiple_data_objects.c
test_archive_read_next_header_empty.c
test_archive_read_next_header_raw.c
test_archive_read_open2.c
test_archive_read_set_filter_option.c
test_archive_read_set_format_option.c
test_archive_read_set_option.c
test_archive_read_set_options.c
test_archive_read_support.c
test_archive_set_error.c
test_archive_string.c
test_archive_string_conversion.c
test_archive_write_add_filter_by_name.c
test_archive_write_set_filter_option.c
test_archive_write_set_format_by_name.c
test_archive_write_set_format_option.c
test_archive_write_set_option.c
test_archive_write_set_options.c
test_bad_fd.c
test_compat_bzip2.c
test_compat_cpio.c
test_compat_gtar.c
test_compat_gzip.c
test_compat_lzip.c
test_compat_lzma.c
test_compat_lzop.c
test_compat_mac.c
test_compat_pax_libarchive_2x.c
test_compat_solaris_tar_acl.c
test_compat_solaris_pax_sparse.c
test_compat_tar_hardlink.c
test_compat_uudecode.c
test_compat_xz.c
test_compat_zip.c
test_empty_write.c
test_entry.c
test_entry_strmode.c
test_extattr_freebsd.c
test_filter_count.c
test_fuzz.c
test_gnutar_filename_encoding.c
test_link_resolver.c
test_open_failure.c
test_open_fd.c
test_open_file.c
test_open_filename.c
test_pax_filename_encoding.c
test_read_data_large.c
test_read_disk.c
test_read_disk_directory_traversals.c
test_read_disk_entry_from_file.c
test_read_extract.c
test_read_file_nonexistent.c
test_read_filter_grzip.c
test_read_filter_lrzip.c
test_read_filter_lzop.c
test_read_filter_lzop_multiple_parts.c
test_read_filter_program.c
test_read_filter_program_signature.c
test_read_filter_uudecode.c
test_read_format_7zip.c
test_read_format_ar.c
test_read_format_cab.c
test_read_format_cab_filename.c
test_read_format_cpio_afio.c
test_read_format_cpio_bin.c
test_read_format_cpio_bin_Z.c
test_read_format_cpio_bin_be.c
test_read_format_cpio_bin_bz2.c
test_read_format_cpio_bin_gz.c
test_read_format_cpio_bin_lzip.c
test_read_format_cpio_bin_lzma.c
test_read_format_cpio_bin_xz.c
test_read_format_cpio_filename.c
test_read_format_cpio_odc.c
test_read_format_cpio_svr4_bzip2_rpm.c
test_read_format_cpio_svr4_gzip.c
test_read_format_cpio_svr4_gzip_rpm.c
test_read_format_cpio_svr4c_Z.c
test_read_format_empty.c
test_read_format_gtar_filename.c
test_read_format_gtar_gz.c
test_read_format_gtar_lzma.c
test_read_format_gtar_sparse.c
test_read_format_iso_Z.c
test_read_format_iso_multi_extent.c
test_read_format_iso_xorriso.c
test_read_format_isojoliet_bz2.c
test_read_format_isojoliet_long.c
test_read_format_isojoliet_rr.c
test_read_format_isojoliet_versioned.c
test_read_format_isorr_bz2.c
test_read_format_isorr_ce.c
test_read_format_isorr_new_bz2.c
test_read_format_isorr_rr_moved.c
test_read_format_isozisofs_bz2.c
test_read_format_lha.c
test_read_format_lha_filename.c
test_read_format_mtree.c
test_read_format_pax_bz2.c
test_read_format_rar.c
test_read_format_raw.c
test_read_format_tar.c
test_read_format_tar_empty_filename.c
test_read_format_tar_filename.c
test_read_format_tbz.c
test_read_format_tgz.c
test_read_format_tlz.c
test_read_format_txz.c
test_read_format_tz.c
test_read_format_ustar_filename.c
test_read_format_xar.c
test_read_format_zip.c
test_read_format_zip_comment_stored.c
test_read_format_zip_filename.c
test_read_format_zip_mac_metadata.c
test_read_format_zip_sfx.c
test_read_large.c
test_read_pax_truncated.c
test_read_position.c
test_read_set_format.c
test_read_truncated.c
test_read_truncated_filter.c
test_sparse_basic.c
test_tar_filenames.c
test_tar_large.c
test_ustar_filenames.c
test_ustar_filename_encoding.c
test_write_disk.c
test_write_disk_appledouble.c
test_write_disk_failures.c
test_write_disk_hardlink.c
test_write_disk_hfs_compression.c
test_write_disk_lookup.c
test_write_disk_mac_metadata.c
test_write_disk_no_hfs_compression.c
test_write_disk_perms.c
test_write_disk_secure.c
test_write_disk_sparse.c
test_write_disk_symlink.c
test_write_disk_times.c
test_write_filter_b64encode.c
test_write_filter_bzip2.c
test_write_filter_compress.c
test_write_filter_gzip.c
test_write_filter_gzip_timestamp.c
test_write_filter_lrzip.c
test_write_filter_lzip.c
test_write_filter_lzma.c
test_write_filter_lzop.c
test_write_filter_program.c
test_write_filter_uuencode.c
test_write_filter_xz.c
test_write_format_7zip.c
test_write_format_7zip_empty.c
test_write_format_7zip_large.c
test_write_format_ar.c
test_write_format_cpio.c
test_write_format_cpio_empty.c
test_write_format_cpio_newc.c
test_write_format_cpio_odc.c
test_write_format_gnutar.c
test_write_format_iso9660.c
test_write_format_iso9660_boot.c
test_write_format_iso9660_empty.c
test_write_format_iso9660_filename.c
test_write_format_iso9660_zisofs.c
test_write_format_mtree.c
test_write_format_mtree_absolute_path.c
test_write_format_mtree_classic.c
test_write_format_mtree_classic_indent.c
test_write_format_mtree_fflags.c
test_write_format_mtree_no_separator.c
test_write_format_mtree_quoted_filename.c
test_write_format_pax.c
test_write_format_shar_empty.c
test_write_format_tar.c
test_write_format_tar_empty.c
test_write_format_tar_sparse.c
test_write_format_tar_ustar.c
test_write_format_tar_v7tar.c
test_write_format_xar.c
test_write_format_xar_empty.c
test_write_format_zip.c
test_write_format_zip_empty.c
test_write_format_zip_no_compression.c
test_write_zip_set_compression_store.c
test_write_open_memory.c
test_zip_filename_encoding.c
)
#
# Register target
#
ADD_EXECUTABLE(libarchive_test ${libarchive_test_SOURCES})
TARGET_LINK_LIBRARIES(libarchive_test archive_static ${ADDITIONAL_LIBS})
SET_PROPERTY(TARGET libarchive_test PROPERTY COMPILE_DEFINITIONS
LIBARCHIVE_STATIC LIST_H)
#
# Generate list.h by grepping DEFINE_TEST() lines out of the C sources.
#
GENERATE_LIST_H(${CMAKE_CURRENT_BINARY_DIR}/list.h
${CMAKE_CURRENT_LIST_FILE} ${libarchive_test_SOURCES})
SET_PROPERTY(DIRECTORY APPEND PROPERTY INCLUDE_DIRECTORIES
${CMAKE_CURRENT_BINARY_DIR})
# list.h has a line DEFINE_TEST(testname) for every
# test. We can use that to define the tests for cmake by
# defining a DEFINE_TEST macro and reading list.h in.
MACRO (DEFINE_TEST _testname)
ADD_TEST(
NAME libarchive_${_testname}
COMMAND libarchive_test -vv
-r ${CMAKE_CURRENT_SOURCE_DIR}
${_testname})
ENDMACRO (DEFINE_TEST _testname)
INCLUDE(${CMAKE_CURRENT_BINARY_DIR}/list.h)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/test_utils)
# Experimental new test handling
ADD_CUSTOM_TARGET(run_libarchive_test
COMMAND libarchive_test -r ${CMAKE_CURRENT_SOURCE_DIR})
ADD_DEPENDENCIES(run_all_tests run_libarchive_test)
ENDIF(ENABLE_TEST)

49
tar/CMakeLists.txt Normal file
View File

@ -0,0 +1,49 @@
############################################
#
# How to build bsdtar
#
############################################
IF(ENABLE_TAR)
SET(bsdtar_SOURCES
bsdtar.c
bsdtar.h
bsdtar_platform.h
cmdline.c
creation_set.c
read.c
subst.c
util.c
write.c
../libarchive_fe/err.c
../libarchive_fe/err.h
../libarchive_fe/lafe_platform.h
../libarchive_fe/line_reader.c
../libarchive_fe/line_reader.h
)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libarchive_fe)
IF(WIN32 AND NOT CYGWIN)
LIST(APPEND bsdtar_SOURCES bsdtar_windows.c)
LIST(APPEND bsdtar_SOURCES bsdtar_windows.h)
ENDIF(WIN32 AND NOT CYGWIN)
# bsdtar documentation
SET(bsdtar_MANS bsdtar.1)
# How to build bsdtar
ADD_EXECUTABLE(bsdtar ${bsdtar_SOURCES})
IF(ENABLE_TAR_SHARED)
TARGET_LINK_LIBRARIES(bsdtar archive ${ADDITIONAL_LIBS})
ELSE(ENABLE_TAR_SHARED)
TARGET_LINK_LIBRARIES(bsdtar archive_static ${ADDITIONAL_LIBS})
SET_TARGET_PROPERTIES(bsdtar PROPERTIES COMPILE_DEFINITIONS
LIBARCHIVE_STATIC)
ENDIF(ENABLE_TAR_SHARED)
GET_TARGET_PROPERTY(BSDTAR bsdtar LOCATION)
# Installation rules
INSTALL(TARGETS bsdtar RUNTIME DESTINATION bin)
INSTALL_MAN(${bsdtar_MANS})
ENDIF(ENABLE_TAR)
add_subdirectory(test)

298
tar/bsdtar_windows.c Normal file
View File

@ -0,0 +1,298 @@
/*-
* Copyright (c) 2009 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$
*/
#if defined(_WIN32) && !defined(__CYGWIN__)
#include "bsdtar_platform.h"
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <io.h>
#include <stddef.h>
#ifdef HAVE_SYS_UTIME_H
#include <sys/utime.h>
#endif
#include <sys/stat.h>
#include <process.h>
#include <stdlib.h>
#include <wchar.h>
#include <windows.h>
#include <sddl.h>
#include "bsdtar.h"
#include "err.h"
/* This may actually not be needed anymore.
* TODO: Review the error handling for chdir() failures and
* simply dump this if it's not really needed. */
static void __tar_dosmaperr(unsigned long);
/*
* Prepend "\\?\" to the path name and convert it to unicode to permit
* an extended-length path for a maximum total path length of 32767
* characters.
* see also http://msdn.microsoft.com/en-us/library/aa365247.aspx
*/
static wchar_t *
permissive_name(const char *name)
{
wchar_t *wn, *wnp;
wchar_t *ws, *wsp;
DWORD l, len, slen, alloclen;
int unc;
len = (DWORD)strlen(name);
wn = malloc((len + 1) * sizeof(wchar_t));
if (wn == NULL)
return (NULL);
l = MultiByteToWideChar(CP_ACP, 0, name, len, wn, len);
if (l == 0) {
free(wn);
return (NULL);
}
wn[l] = L'\0';
/* Get a full path names */
l = GetFullPathNameW(wn, 0, NULL, NULL);
if (l == 0) {
free(wn);
return (NULL);
}
wnp = malloc(l * sizeof(wchar_t));
if (wnp == NULL) {
free(wn);
return (NULL);
}
len = GetFullPathNameW(wn, l, wnp, NULL);
free(wn);
wn = wnp;
if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
wnp[2] == L'?' && wnp[3] == L'\\')
/* We have already permissive names. */
return (wn);
if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
wnp[2] == L'.' && wnp[3] == L'\\') {
/* Device names */
if (((wnp[4] >= L'a' && wnp[4] <= L'z') ||
(wnp[4] >= L'A' && wnp[4] <= L'Z')) &&
wnp[5] == L':' && wnp[6] == L'\\')
wnp[2] = L'?';/* Not device names. */
return (wn);
}
unc = 0;
if (wnp[0] == L'\\' && wnp[1] == L'\\' && wnp[2] != L'\\') {
wchar_t *p = &wnp[2];
/* Skip server-name letters. */
while (*p != L'\\' && *p != L'\0')
++p;
if (*p == L'\\') {
wchar_t *rp = ++p;
/* Skip share-name letters. */
while (*p != L'\\' && *p != L'\0')
++p;
if (*p == L'\\' && p != rp) {
/* Now, match patterns such as
* "\\server-name\share-name\" */
wnp += 2;
len -= 2;
unc = 1;
}
}
}
alloclen = slen = 4 + (unc * 4) + len + 1;
ws = wsp = malloc(slen * sizeof(wchar_t));
if (ws == NULL) {
free(wn);
return (NULL);
}
/* prepend "\\?\" */
wcsncpy(wsp, L"\\\\?\\", 4);
wsp += 4;
slen -= 4;
if (unc) {
/* append "UNC\" ---> "\\?\UNC\" */
wcsncpy(wsp, L"UNC\\", 4);
wsp += 4;
slen -= 4;
}
wcsncpy(wsp, wnp, slen);
free(wn);
ws[alloclen - 1] = L'\0';
return (ws);
}
int
__tar_chdir(const char *path)
{
wchar_t *ws;
int r;
r = SetCurrentDirectoryA(path);
if (r == 0) {
if (GetLastError() != ERROR_FILE_NOT_FOUND) {
__tar_dosmaperr(GetLastError());
return (-1);
}
} else
return (0);
ws = permissive_name(path);
if (ws == NULL) {
errno = EINVAL;
return (-1);
}
r = SetCurrentDirectoryW(ws);
free(ws);
if (r == 0) {
__tar_dosmaperr(GetLastError());
return (-1);
}
return (0);
}
/*
* The following function was modified from PostgreSQL sources and is
* subject to the copyright below.
*/
/*-------------------------------------------------------------------------
*
* win32error.c
* Map win32 error codes to errno values
*
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/port/win32error.c,v 1.4 2008/01/01 19:46:00 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
PostgreSQL Database Management System
(formerly known as Postgres, then as Postgres95)
Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
Portions Copyright (c) 1994, The Regents of the University of California
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose, without fee, and without a written agreement
is hereby granted, provided that the above copyright notice and this
paragraph and the following two paragraphs appear in all copies.
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
static const struct {
DWORD winerr;
int doserr;
} doserrors[] =
{
{ ERROR_INVALID_FUNCTION, EINVAL },
{ ERROR_FILE_NOT_FOUND, ENOENT },
{ ERROR_PATH_NOT_FOUND, ENOENT },
{ ERROR_TOO_MANY_OPEN_FILES, EMFILE },
{ ERROR_ACCESS_DENIED, EACCES },
{ ERROR_INVALID_HANDLE, EBADF },
{ ERROR_ARENA_TRASHED, ENOMEM },
{ ERROR_NOT_ENOUGH_MEMORY, ENOMEM },
{ ERROR_INVALID_BLOCK, ENOMEM },
{ ERROR_BAD_ENVIRONMENT, E2BIG },
{ ERROR_BAD_FORMAT, ENOEXEC },
{ ERROR_INVALID_ACCESS, EINVAL },
{ ERROR_INVALID_DATA, EINVAL },
{ ERROR_INVALID_DRIVE, ENOENT },
{ ERROR_CURRENT_DIRECTORY, EACCES },
{ ERROR_NOT_SAME_DEVICE, EXDEV },
{ ERROR_NO_MORE_FILES, ENOENT },
{ ERROR_LOCK_VIOLATION, EACCES },
{ ERROR_SHARING_VIOLATION, EACCES },
{ ERROR_BAD_NETPATH, ENOENT },
{ ERROR_NETWORK_ACCESS_DENIED, EACCES },
{ ERROR_BAD_NET_NAME, ENOENT },
{ ERROR_FILE_EXISTS, EEXIST },
{ ERROR_CANNOT_MAKE, EACCES },
{ ERROR_FAIL_I24, EACCES },
{ ERROR_INVALID_PARAMETER, EINVAL },
{ ERROR_NO_PROC_SLOTS, EAGAIN },
{ ERROR_DRIVE_LOCKED, EACCES },
{ ERROR_BROKEN_PIPE, EPIPE },
{ ERROR_DISK_FULL, ENOSPC },
{ ERROR_INVALID_TARGET_HANDLE, EBADF },
{ ERROR_INVALID_HANDLE, EINVAL },
{ ERROR_WAIT_NO_CHILDREN, ECHILD },
{ ERROR_CHILD_NOT_COMPLETE, ECHILD },
{ ERROR_DIRECT_ACCESS_HANDLE, EBADF },
{ ERROR_NEGATIVE_SEEK, EINVAL },
{ ERROR_SEEK_ON_DEVICE, EACCES },
{ ERROR_DIR_NOT_EMPTY, ENOTEMPTY },
{ ERROR_NOT_LOCKED, EACCES },
{ ERROR_BAD_PATHNAME, ENOENT },
{ ERROR_MAX_THRDS_REACHED, EAGAIN },
{ ERROR_LOCK_FAILED, EACCES },
{ ERROR_ALREADY_EXISTS, EEXIST },
{ ERROR_FILENAME_EXCED_RANGE, ENOENT },
{ ERROR_NESTING_NOT_ALLOWED, EAGAIN },
{ ERROR_NOT_ENOUGH_QUOTA, ENOMEM }
};
static void
__tar_dosmaperr(unsigned long e)
{
int i;
if (e == 0) {
errno = 0;
return;
}
for (i = 0; i < (int)sizeof(doserrors); i++) {
if (doserrors[i].winerr == e) {
errno = doserrors[i].doserr;
return;
}
}
/* fprintf(stderr, "unrecognized win32 error code: %lu", e); */
errno = EINVAL;
return;
}
#endif

60
tar/bsdtar_windows.h Normal file
View File

@ -0,0 +1,60 @@
/*-
* Copyright (c) 2009 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 BSDTAR_WINDOWS_H
#define BSDTAR_WINDOWS_H 1
#include <direct.h>
#include <windows.h>
#ifndef PRId64
#define PRId64 "I64"
#endif
#define geteuid() 0
#ifndef S_IFIFO
#define S_IFIFO 0010000 /* pipe */
#endif
#include <string.h> /* Must include before redefining 'strdup' */
#if !defined(__BORLANDC__)
#define strdup _strdup
#endif
#if !defined(__BORLANDC__)
#define getcwd _getcwd
#endif
#define chdir __tar_chdir
int __tar_chdir(const char *);
#ifndef S_ISREG
#define S_ISREG(a) (a & _S_IFREG)
#endif
#ifndef S_ISBLK
#define S_ISBLK(a) (0)
#endif
#endif /* BSDTAR_WINDOWS_H */

84
tar/config_freebsd.h Normal file
View File

@ -0,0 +1,84 @@
/*-
* 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$
*/
/* A default configuration for FreeBSD, used if there is no config.h. */
#include <sys/param.h> /* __FreeBSD_version */
#undef HAVE_ATTR_XATTR_H
#define HAVE_CHROOT 1
#define HAVE_DIRENT_D_NAMLEN 1
#define HAVE_DIRENT_H 1
#define HAVE_D_MD_ORDER 1
#define HAVE_ERRNO_H 1
#undef HAVE_EXT2FS_EXT2_FS_H
#define HAVE_FCHDIR 1
#define HAVE_FCNTL_H 1
#define HAVE_GRP_H 1
#define HAVE_LANGINFO_H 1
#undef HAVE_LIBACL
#define HAVE_LIBARCHIVE 1
#define HAVE_LIMITS_H 1
#define HAVE_LINK 1
#undef HAVE_LINUX_EXT2_FS_H
#undef HAVE_LINUX_FS_H
#define HAVE_LOCALE_H 1
#define HAVE_MBTOWC 1
#undef HAVE_NDIR_H
#if __FreeBSD_version >= 450002 /* nl_langinfo introduced */
#define HAVE_NL_LANGINFO 1
#endif
#define HAVE_PATHS_H 1
#define HAVE_PWD_H 1
#define HAVE_READLINK 1
#define HAVE_REGEX_H 1
#define HAVE_SETLOCALE 1
#define HAVE_SIGNAL_H 1
#define HAVE_STDARG_H 1
#define HAVE_STDLIB_H 1
#define HAVE_STRING_H 1
#define HAVE_STRUCT_STAT_ST_FLAGS 1
#undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
#undef HAVE_STRUCT_STAT_ST_MTIME_N
#undef HAVE_STRUCT_STAT_ST_MTIME_USEC
#define HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1
#undef HAVE_STRUCT_STAT_ST_UMTIME
#define HAVE_SYMLINK 1
#define HAVE_SYS_CDEFS_H 1
#undef HAVE_SYS_DIR_H
#define HAVE_SYS_IOCTL_H 1
#undef HAVE_SYS_NDIR_H
#define HAVE_SYS_PARAM_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_TIME_H 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_UINTMAX_T 1
#define HAVE_UNISTD_H 1
#define HAVE_UNSIGNED_LONG_LONG
#define HAVE_WCTYPE_H 1
#define HAVE_ZLIB_H 1
#undef MAJOR_IN_MKDEV

101
tar/test/CMakeLists.txt Normal file
View File

@ -0,0 +1,101 @@
############################################
#
# How to build bsdtar_test
#
############################################
IF(ENABLE_TAR AND ENABLE_TEST)
SET(bsdtar_test_SOURCES
../../test_utils/test_utils.c
main.c
test.h
test_0.c
test_basic.c
test_copy.c
test_empty_mtree.c
test_extract_tar_Z.c
test_extract_tar_bz2.c
test_extract_tar_grz.c
test_extract_tar_gz.c
test_extract_tar_lrz.c
test_extract_tar_lz.c
test_extract_tar_lzma.c
test_extract_tar_lzo.c
test_extract_tar_xz.c
test_format_newc.c
test_help.c
test_option_C_upper.c
test_option_H_upper.c
test_option_L_upper.c
test_option_O_upper.c
test_option_T_upper.c
test_option_U_upper.c
test_option_X_upper.c
test_option_a.c
test_option_b.c
test_option_b64encode.c
test_option_exclude.c
test_option_gid_gname.c
test_option_grzip.c
test_option_j.c
test_option_k.c
test_option_keep_newer_files.c
test_option_lrzip.c
test_option_lzma.c
test_option_lzop.c
test_option_n.c
test_option_newer_than.c
test_option_nodump.c
test_option_older_than.c
test_option_q.c
test_option_r.c
test_option_s.c
test_option_uid_uname.c
test_option_uuencode.c
test_option_xz.c
test_option_z.c
test_patterns.c
test_print_longpath.c
test_stdio.c
test_strip_components.c
test_symlink_dir.c
test_version.c
test_windows.c
)
#
# Register target
#
ADD_EXECUTABLE(bsdtar_test ${bsdtar_test_SOURCES})
SET_PROPERTY(TARGET bsdtar_test PROPERTY COMPILE_DEFINITIONS LIST_H)
#
# Generate list.h by grepping DEFINE_TEST() lines out of the C sources.
#
GENERATE_LIST_H(${CMAKE_CURRENT_BINARY_DIR}/list.h
${CMAKE_CURRENT_LIST_FILE} ${bsdtar_test_SOURCES})
SET_PROPERTY(DIRECTORY APPEND PROPERTY INCLUDE_DIRECTORIES
${CMAKE_CURRENT_BINARY_DIR})
# list.h has a line DEFINE_TEST(testname) for every
# test. We can use that to define the tests for cmake by
# defining a DEFINE_TEST macro and reading list.h in.
MACRO (DEFINE_TEST _testname)
ADD_TEST(
NAME bsdtar_${_testname}
COMMAND bsdtar_test -vv
-p $<TARGET_FILE:bsdtar>
-r ${CMAKE_CURRENT_SOURCE_DIR}
${_testname})
ENDMACRO (DEFINE_TEST _testname)
INCLUDE(${CMAKE_CURRENT_BINARY_DIR}/list.h)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/test_utils)
# Experimental new test handling
ADD_CUSTOM_TARGET(run_bsdtar_test
COMMAND bsdtar_test -p ${BSDTAR} -r ${CMAKE_CURRENT_SOURCE_DIR})
ADD_DEPENDENCIES(run_bsdtar_test bsdtar)
ADD_DEPENDENCIES(run_all_tests run_bsdtar_test)
ENDIF(ENABLE_TAR AND ENABLE_TEST)

324
tar/test/test_windows.c Normal file
View File

@ -0,0 +1,324 @@
/*-
* Copyright (c) 2009 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 "test.h"
#if defined(_WIN32) && !defined(__CYGWIN__)
#include <direct.h>
#include <windows.h>
static void
mkfile(const char *name)
{
FILE *f;
f = fopen(name, "wb");
assert(f != NULL);
assertEqualInt(5, fwrite("01234", 1, 5, f));
fclose(f);
}
static void
mkfullpath(char **path1, char **path2, const char *tpath, int type)
{
char *fp1 = NULL, *fp2 = NULL, *p1 = NULL, *p2 = NULL;
size_t l;
/*
* Get full path name of "tpath"
*/
l = GetFullPathNameA(tpath, 0, NULL, NULL);
assert(0 != l);
fp1 = malloc(l);
assert(NULL != fp1);
fp2 = malloc(l*2);
assert(NULL != fp2);
l = GetFullPathNameA(tpath, (DWORD)l, fp1, NULL);
if ((type & 0x01) == 0) {
for (p1 = fp1; *p1 != '\0'; p1++)
if (*p1 == '\\')
*p1 = '/';
}
switch(type) {
case 0: /* start with "/" */
case 1: /* start with "\" */
/* strip "c:" */
memmove(fp1, fp1 + 2, l - 2);
fp1[l -2] = '\0';
p1 = fp1 + 1;
break;
case 2: /* start with "c:/" */
case 3: /* start with "c:\" */
p1 = fp1 + 3;
break;
case 4: /* start with "//./c:/" */
case 5: /* start with "\\.\c:\" */
case 6: /* start with "//?/c:/" */
case 7: /* start with "\\?\c:\" */
p1 = malloc(l + 4 + 1);
assert(NULL != p1);
if (type & 0x1)
memcpy(p1, "\\\\.\\", 4);
else
memcpy(p1, "//./", 4);
if (type == 6 || type == 7)
p1[2] = '?';
memcpy(p1 + 4, fp1, l);
p1[l + 4] = '\0';
free(fp1);
fp1 = p1;
p1 = fp1 + 7;
break;
}
/*
* Strip leading drive names and converting "\" to "\\"
*/
p2 = fp2;
while (*p1 != '\0') {
if (*p1 == '\\')
*p2 = '/';
else
*p2 = *p1;
++p1;
++p2;
}
*p2++ = '\r';
*p2++ = '\n';
*p2 = '\0';
*path1 = fp1;
*path2 = fp2;
}
static const char *list1[] = {"aaa/", "aaa/file1", "aaa/xxa/", "aaa/xxb/",
"aaa/zzc/", "aaa/zzc/file1", "aaa/xxb/file1", "aaa/xxa/file1",
"aab/", "aac/", "abb/", "abc/", "abd/", NULL};
static const char *list2[] = {"bbb/", "bbb/file1", "bbb/xxa/", "bbb/xxb/",
"bbb/zzc/", "bbb/zzc/file1", "bbb/xxb/file1", "bbb/xxa/file1", "bbc/",
"bbd/", "bcc/", "bcd/", "bce/", NULL};
static const char *list3[] = {"aac/", "abc/", "bbc/", "bcc/", "ccc/", NULL};
static const char *list4[] = {"fff/abca", "fff/acca", NULL};
static const char *list5[] = {"aaa/file1", "aaa/xxa/", "aaa/xxa/file1",
"aaa/xxb/", "aaa/xxb/file1", "aaa/zzc/", "aaa/zzc/file1", NULL};
static const char *list6[] = {"fff/abca", "fff/acca", "aaa/xxa/",
"aaa/xxa/file1", "aaa/xxb/", "aaa/xxb/file1", NULL};
#endif /* _WIN32 && !__CYGWIN__ */
DEFINE_TEST(test_windows)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
char *fp1, *fp2;
/*
* Preparre tests.
* Create directories and files.
*/
assertMakeDir("tmp", 0775);
assertChdir("tmp");
assertMakeDir("aaa", 0775);
assertMakeDir("aaa/xxa", 0775);
assertMakeDir("aaa/xxb", 0775);
assertMakeDir("aaa/zzc", 0775);
mkfile("aaa/file1");
mkfile("aaa/xxa/file1");
mkfile("aaa/xxb/file1");
mkfile("aaa/zzc/file1");
assertMakeDir("aab", 0775);
assertMakeDir("aac", 0775);
assertMakeDir("abb", 0775);
assertMakeDir("abc", 0775);
assertMakeDir("abd", 0775);
assertMakeDir("bbb", 0775);
assertMakeDir("bbb/xxa", 0775);
assertMakeDir("bbb/xxb", 0775);
assertMakeDir("bbb/zzc", 0775);
mkfile("bbb/file1");
mkfile("bbb/xxa/file1");
mkfile("bbb/xxb/file1");
mkfile("bbb/zzc/file1");
assertMakeDir("bbc", 0775);
assertMakeDir("bbd", 0775);
assertMakeDir("bcc", 0775);
assertMakeDir("bcd", 0775);
assertEqualInt(0, _mkdir("bce"));
assertEqualInt(0, _mkdir("ccc"));
assertEqualInt(0, _mkdir("fff"));
mkfile("fff/aaaa");
mkfile("fff/abba");
mkfile("fff/abca");
mkfile("fff/acba");
mkfile("fff/acca");
/*
* Test1: Command line pattern matching.
*/
assertEqualInt(0,
systemf("%s -cf ../archive1.tar a*", testprog));
assertEqualInt(0,
systemf("%s -tf ../archive1.tar > ../list1", testprog));
assertFileContainsLinesAnyOrder("../list1", list1);
assertEqualInt(0,
systemf("%s -cf ../archive2.tar b*", testprog));
assertEqualInt(0,
systemf("%s -tf ../archive2.tar > ../list2", testprog));
assertFileContainsLinesAnyOrder("../list2", list2);
assertEqualInt(0,
systemf("%s -cf ../archive3.tar ??c", testprog));
assertEqualInt(0,
systemf("%s -tf ../archive3.tar > ../list3", testprog));
assertFileContainsLinesAnyOrder("../list3", list3);
assertEqualInt(0,
systemf("%s -cf ../archive3b.tar *c", testprog));
assertEqualInt(0,
systemf("%s -tf ../archive3b.tar > ../list3b", testprog));
assertFileContainsLinesAnyOrder("../list3b", list3);
assertEqualInt(0,
systemf("%s -cf ../archive4.tar fff/a?ca", testprog));
assertEqualInt(0,
systemf("%s -tf ../archive4.tar > ../list4", testprog));
assertFileContainsLinesAnyOrder("../list4", list4);
assertEqualInt(0,
systemf("%s -cf ../archive5.tar aaa\\*", testprog));
assertEqualInt(0,
systemf("%s -tf ../archive5.tar > ../list5", testprog));
assertFileContainsLinesAnyOrder("../list5", list5);
assertEqualInt(0,
systemf("%s -cf ../archive6.tar fff\\a?ca aaa\\xx*", testprog));
assertEqualInt(0,
systemf("%s -tf ../archive6.tar > ../list6", testprog));
assertFileContainsLinesAnyOrder("../list6", list6);
/*
* Test2: Archive the file start with drive letters.
*/
/* Test2a: start with "/" */
mkfullpath(&fp1, &fp2, "aaa/file1", 0);
assertEqualInt(0,
systemf("%s -cf ../archive10.tar %s > ../out10 2> ../err10",
testprog, fp1));
assertEqualInt(0,
systemf("%s -tf ../archive10.tar > ../list10", testprog));
/* Check drive letters have been stripped. */
assertFileContents(fp2, (int)strlen(fp2), "../list10");
free(fp1);
free(fp2);
/* Test2b: start with "\" */
mkfullpath(&fp1, &fp2, "aaa/file1", 1);
assertEqualInt(0,
systemf("%s -cf ../archive11.tar %s > ../out11 2> ../err11",
testprog, fp1));
assertEqualInt(0,
systemf("%s -tf ../archive11.tar > ../list11", testprog));
/* Check drive letters have been stripped. */
assertFileContents(fp2, (int)strlen(fp2), "../list11");
free(fp1);
free(fp2);
/* Test2c: start with "c:/" */
mkfullpath(&fp1, &fp2, "aaa/file1", 2);
assertEqualInt(0,
systemf("%s -cf ../archive12.tar %s > ../out12 2> ../err12",
testprog, fp1));
assertEqualInt(0,
systemf("%s -tf ../archive12.tar > ../list12", testprog));
/* Check drive letters have been stripped. */
assertFileContents(fp2, (int)strlen(fp2), "../list12");
free(fp1);
free(fp2);
/* Test2d: start with "c:\" */
mkfullpath(&fp1, &fp2, "aaa/file1", 3);
assertEqualInt(0,
systemf("%s -cf ../archive13.tar %s > ../out13 2> ../err13",
testprog, fp1));
assertEqualInt(0,
systemf("%s -tf ../archive13.tar > ../list13", testprog));
/* Check drive letters have been stripped. */
assertFileContents(fp2, (int)strlen(fp2), "../list13");
free(fp1);
free(fp2);
/* Test2e: start with "//./c:/" */
mkfullpath(&fp1, &fp2, "aaa/file1", 4);
assertEqualInt(0,
systemf("%s -cf ../archive14.tar %s > ../out14 2> ../err14",
testprog, fp1));
assertEqualInt(0,
systemf("%s -tf ../archive14.tar > ../list14", testprog));
/* Check drive letters have been stripped. */
assertFileContents(fp2, (int)strlen(fp2), "../list14");
free(fp1);
free(fp2);
/* Test2f: start with "\\.\c:\" */
mkfullpath(&fp1, &fp2, "aaa/file1", 5);
assertEqualInt(0,
systemf("%s -cf ../archive15.tar %s > ../out15 2> ../err15",
testprog, fp1));
assertEqualInt(0,
systemf("%s -tf ../archive15.tar > ../list15", testprog));
/* Check drive letters have been stripped. */
assertFileContents(fp2, (int)strlen(fp2), "../list15");
free(fp1);
free(fp2);
/* Test2g: start with "//?/c:/" */
mkfullpath(&fp1, &fp2, "aaa/file1", 6);
failure("fp1=%s, fp2=%s", fp1, fp2);
assertEqualInt(0,
systemf("%s -cf ../archive16.tar %s > ../out16 2> ../err16",
testprog, fp1));
assertEqualInt(0,
systemf("%s -tf ../archive16.tar > ../list16", testprog));
/* Check drive letters have been stripped. */
assertFileContents(fp2, (int)strlen(fp2), "../list16");
free(fp1);
free(fp2);
/* Test2h: start with "\\?\c:\" */
mkfullpath(&fp1, &fp2, "aaa/file1", 7);
failure("fp1=%s, fp2=%s", fp1, fp2);
assertEqualInt(0,
systemf("%s -cf ../archive17.tar %s > ../out17 2> ../err17",
testprog, fp1));
assertEqualInt(0,
systemf("%s -tf ../archive17.tar > ../list17", testprog));
/* Check drive letters have been stripped. */
assertFileContents(fp2, (int)strlen(fp2), "../list17");
free(fp1);
free(fp2);
#else
skipping("Windows specific test");
#endif /* _WIN32 && !__CYGWIN__ */
}